arr = ["red","green","blue","yellow"]
arr.each do |colour|
if colour == "red"
colour = "green"
end
end
puts arr.inspect
以上代码输出:
["red", "green", "blue", "yellow"]
但为什么不呢?
["green", "green", "blue", "yellow"]
我认为颜色是对数组中当前元素的引用,无论我对它做什么都会影响该数组元素?
答案 0 :(得分:5)
当您在arr.each
块内时,colour
变量绑定到arr
数组中的一个对象。
但是,只要在块中进行赋值colour = "green"
,现在colour
变量就绑定到一个新对象(即一个值为"green"
的String),并且原arr
保持不受影响。
实现您所谈论的内容的一种方法是:
arr.each_index do |i|
arr[i] = "green" if arr[i] == "red"
end
直接操纵数组。
答案 1 :(得分:4)
Color实际上是对数组中当前元素的引用,但是'color =“green”'它现在引用了一个 new 字符串。旧的保持不变。要进行试验,请尝试替换
colour = "green"
有一个或多个
colour.replace "green"
colour.capitalize! #not capitalize, which would give a new string again
colour << "ish"
所有这些都在现有字符串上运行,而不是创建新字符串。
答案 2 :(得分:4)
通常,为了将数组转换为另一个数组,在Ruby中不使用each
方法,而是使用map
方法(上面的用户sflinter代码):
arr.map { |x| x == "red" ? "green" : x }
或者,考虑到转换图,更为一般:
mapping = {'red' => 'green', 'blue' => 'yellow'}
我们可以做类似
的事情p arr.map {|e| mapping[e] || e} # => ["green", "green", "yellow", "yellow"]
PS:正如Phrogz在下面建议的那样,map
创建了一个新的数组实例,如果你打算将修改后的数组保存在同一个变量中,你应该为它分配map
的结果。
另一方面,map
的邪恶双胞胎称为map!
,它原位修改原始阵列(因此无需将其分配回来),节省了一些空间和时间,但是打破功能不应有副作用的纯函数式编程概念。
答案 3 :(得分:2)
我要编写的是 not 建议的方法,但请注意,由于Strings在Ruby中是可变的,因此您可以编写原始代码,如下所示:
arr.each do |colour|
colour.replace "green" if colour == "red"
end
p arr
#=> ["green", "green", "blue", "yellow"]