为什么不能使用Ruby中的每个do循环填充数组?

时间:2017-01-03 10:29:19

标签: arrays ruby each

如果我使用每个do循环来填充数组,它将保持数组不变(在这种情况下,它将是一个大小为4的nil数组)

array = Array.new(4)
array.each do |i|
  i = 5
end

我知道我可以使用array = Array.new(4) {desired value}使用我想要的值初始化一个数组,但是在某些情况下,我在不同的值之间进行选择,我正在尝试理解每个循环的工作方式。

我正在这样做的当前方式是使用我想要的值填充数组

array = Array.new(4)
array.each_with_index do |val, i|
  array[i] = 5
end

2 个答案:

答案 0 :(得分:4)

解决方案

你需要:

array = Array.new(4) do |i|
  5
  # or some logic depending on i (the index between 0 and 3)
end

您的代码

array = Array.new(4)

数组现在是一个包含4个元素的数组(每次nil)。

array.each迭代这4个元素(仍为nil),并将i设置为块本地变量,等于nil

在此区块内,您使用5覆盖i,但您不会对其执行任何操作。在下一次迭代中,i将重新设置为nil,并设置为5,依此类推......

您不会更改原始数组,只需更改已设置为等于数组元素的局部变量。

答案 1 :(得分:3)

区别在于

$ cat foo
117,2,3   # good
1,117,3   # good
1,2,117   # good
1117,2,3  # bad
1,1117,3  # bad
1,2,1177  # bad
$ awk '$1~/(^|,)117($|,)/' foo
117,2,3   # good
1,117,3   # good
1,2,117   # good

是一项任务。它将值i = 5 分配给变量5

在Ruby中,赋值只影响局部范围,它们不会更改调用者范围内的变量:

i

因此,通过分配变量,无法将数组元素替换为另一个对象。

另一方面,

def change(i)
  i = 5       # <- doesn't work as you might expect
end

x = nil
change(x)
x #=> nil

不是赋值,而是伪装的方法调用。它相当于:

array[i] = 5

array.[]=(i, 5)

它要求数组将索引array.public_send(:[]=, i, 5) 的元素设置为i