fr_*_*awd 2 ruby dictionary reference enumerate
def removal(arr)
letters ="i"
p arr
new_array = arr.map do |c_word|
c_word.each_char.with_index do |char, index|
if letters.include?(char)
c_word[index] = "*"
end
end
end
p arr #the original array is getting edited? why?
p new_array
end
removal(["hiiiiiigh","git", "training"])
Run Code Online (Sandbox Code Playgroud)
在这段代码中,map方法中的原始数组(arr)不断得到编辑。我以为地图不会编辑原始数组。如果需要编辑原始文件,则可以使用.map!
我相信这与嵌套枚举器或我没有看到的变量引用有关。我使用了while循环,而不是each_char.with_index,并且map仍然可以编辑原始数组。为什么要编辑原始数组?
实际上,您至少在以下两个地方错了:
map是不编辑原始阵列如果仔细观察,该数组没有更改,只有该数组中的字符串已更改。它是不是map正在这样做,这是String#[]=,你在呼唤这里:
c_word[index] = "*"
Run Code Online (Sandbox Code Playgroud)
因此,您正在调用一种用于编辑字符串的方法,因此对字符串进行编辑不会感到惊讶!
考虑使用:
map说“我想基于现有数据创建新数据” each说“我要么不想更改任何数据,要么更改现有数据”考虑到这一点,您正在做的事情是map与数组一起使用,以基于现有数组创建新数组,然后each用于修改现有字符串中的字符。这就是为什么原始数组中的字符串最终会被修改的原因。
若要修复此问题map,请先“基于现有数组创建新数组”,然后第二次“基于现有字符串创建新字符串”。这样,原始字符串将不会被修改。
def removal(arr)
letters ="i"
p arr
new_array = arr.map do |word|
word.chars.map do |char|
letters.include?(char) ? '*' : char
end.join
end
p arr
p new_array
end
removal(["hiiiiiigh","git", "training"]) #=> ["hiiiiiigh", "git", "training"]
# ["hiiiiiigh", "git", "training"]
# ["h******gh", "g*t", "tra*n*ng"]
Run Code Online (Sandbox Code Playgroud)
这个问题的更实际的解决方案将是这样的:
def censor(strings, forbidden_chars_string, censor_char = '*')
re = Regexp.union(forbidden_chars_string.chars)
strings.map {|str| str.gsub(re, censor_char) }
end
p ["hiiiiiigh","git", "training"] #=> ["hiiiiiigh", "git", "training"]
p censor(["hiiiiiigh","git", "training"], "i") #=> ["h******gh", "g*t", "tra*n*ng"]
p censor(["hiiiiiigh","git", "training"], "gn", '_') #=> ["hiiiiii_h", "_it", "trai_i__"]
Run Code Online (Sandbox Code Playgroud)