Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 在数组中循环时更改数组中的项_Ruby_Arrays - Fatal编程技术网

Ruby 在数组中循环时更改数组中的项

Ruby 在数组中循环时更改数组中的项,ruby,arrays,Ruby,Arrays,上述代码输出: arr = ["red","green","blue","yellow"] arr.each do |colour| if colour == "red" colour = "green" end end puts arr.inspect 但为什么不呢 ["red", "green", "blue", "yellow"] 我认为颜色是对数组中当前元素的引用,我对它所做的任何操作都会影响该数组元素?当您在arr中时。每个块,color变量都绑定到arr数组中

上述代码输出:

arr = ["red","green","blue","yellow"]

arr.each do |colour|
  if colour == "red"
    colour = "green"
  end
end

puts arr.inspect
但为什么不呢

["red", "green", "blue", "yellow"]

我认为颜色是对数组中当前元素的引用,我对它所做的任何操作都会影响该数组元素?

当您在
arr中时。每个
块,
color
变量都绑定到
arr
数组中的一个对象

但是,一旦在块中赋值
color=“green”
,现在
color
变量就绑定到一个新对象(即值为
“green”
的字符串),并且原始
arr
保持不变

实现您所说目标的一种方法是:

["green", "green", "blue", "yellow"]

它直接操作数组。

颜色最初确实是对数组中当前元素的引用,但使用“color=“green”时,它现在引用一个新的字符串。旧的没有改变。要进行实验,请尝试替换

arr.each_index do |i|
  arr[i] = "green" if arr[i] == "red"
end
与一个或多个

colour = "green"
颜色。替换“绿色”
颜色。大写#不大写,这将再次给出一个新字符串

color通常,为了将一个数组转换为另一个数组,在Ruby中,您不使用
每个
方法,而是使用
映射
方法(上面由用户sflinter编写的代码):

或者,更一般地说,给定转换图:

arr.map { |x| x == "red" ? "green" : x }
我们可以这样做

mapping = {'red' => 'green', 'blue' => 'yellow'}
PS:正如Phrogz在下面建议的那样,
map
创建一个新的数组实例,如果您计划将修改后的数组保留在同一个变量中,您应该将
map
的结果分配给它


另一方面,
map
的邪恶孪生兄弟叫
map,它修改了原始数组(因此无需重新分配),节省了一些空间和时间,但打破了函数不应有副作用的纯函数式编程概念。

我将要写的不是推荐的方法,但请注意,由于字符串在Ruby中是可变的,因此可以按如下方式编写原始代码:

p arr.map {|e| mapping[e] || e} # => ["green", "green", "yellow", "yellow"]

<>代码> map > <代码>可能更好。同意,代码> AR.map {{x x==“红色”“绿色”:x}也会很好。C++中,“引用”的概念被描述为一个巫毒玩偶,无论你对引用做什么,你实际上都在做指向的对象。Ruby中引用的概念似乎完全不同。除了我上面的评论,考虑到我原始示例中的变量“color”,您如何操作它直接指向的内存,而不是变量本身,而不使用任何特定的数组函数?我想我要问的是color.replace在引擎盖下做什么?@pingu
color
不是一个参考;它是一个变量,包含对另一个对象的引用。变量赋值总是用不同的引用替换变量的内容,而方法调用是在被引用的对象上执行的。您应该修改答案,以澄清
map
返回新数组和需要将其赋值给新变量与
map的可用性之间的区别用于就地突变.map evil twin非常适合保存代码行,我经常使用它,但在遇到意外情况(如nils等)时更容易出错。我编辑了一个包含突变对象的注释,使用它可以使用索引并获得所需结果:arr.each{color | color[0..color.length]如果颜色为红色,则为绿色
p arr.map {|e| mapping[e] || e} # => ["green", "green", "yellow", "yellow"]
arr.each do |colour|
  colour.replace "green" if colour == "red"
end

p arr
#=> ["green", "green", "blue", "yellow"]