尝试更改使用迭代创建的数组中的单个值会更改多个值。为什么?

时间:2018-06-12 14:42:23

标签: arrays ruby iterator

a = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
b = []
row = []
3.times { row << 0 }
3.times { b << row }

p a #=> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
p b #=> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
p a == b                         #=> true
p (a[1][1] = 1) == (b[1][1] = 1) #=> true

# and yet ...
a[1][1] = 1
b[1][1] = 1
p a #=> [[0, 0, 0], [0, 1, 0], [0, 0, 0]]
p b #=> [[0, 1, 0], [0, 1, 0], [0, 1, 0]]

使用此代码,我希望修改后的b与修改后的a相同,但相反,每个嵌套数组的第二个元素都会被修改。

我错过了什么?为什么a[1][1] = 1b[1][1] = 1会产生不同的结果?

1 个答案:

答案 0 :(得分:3)

3.times { b << row }行将相同数组的3个引用添加到b,因此修改它一次会在数组中将其更改三次。

尝试将此行更新为dup,并将其推送到b,即3.times { b << row.dup }

(因为我正在打字我看到@mudasobwa在评论中打败了我:))

这种方法将确保b填充三个唯一的数组,而不是相同的三个数组。

如果您不确定,可以查看object_id,即b.map(&:object_id) - 目前,这些都是相同的。