这里的问题是b = Array.new(3, [])
使用相同的对象对于所有的阵列单元基值:
b = Array.new(3, [])
b[0].object_id #=> 28424380
b[1].object_id #=> 28424380
b[2].object_id #=> 28424380
所以当你使用b[0].push
,它添加项目“每个”子阵列,因为他们都是,实际上,在同一阵列。
那么为什么b [0] + = [“value”]有效?好了,看着红宝石文档:
元+ other_ary→new_ary
级联 - 返回由两个数组串联起来,以产生第三阵列建立了一个新的数组。
[ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
a = [ "a", "b", "c" ]
c = a + [ "d", "e", "f" ]
c #=> [ "a", "b", "c", "d", "e", "f" ]
a #=> [ "a", "b", "c" ]
注意
x += y
相同
x = x + y
这意味着它会产生一个新的数组。结果,在数组上重复使用+ =会非常低效。
所以当你使用+=
,它完全取代了数组,这意味着在b[0]
数组不再一样b[1]
或b[2]
。
正如你可以看到:
b = Array.new(3, [])
b[0].push("test")
b #=> [["test"], ["test"], ["test"]]
b[0].object_id #=> 28424380
b[1].object_id #=> 28424380
b[2].object_id #=> 28424380
b[0] += ["foo"]
b #=> [["test", "foo"], ["test"], ["test"]]
b[0].object_id #=> 38275912
b[1].object_id #=> 28424380
b[2].object_id #=> 28424380
如果你想知道如何保证每个数组初始化独特数组的数组时,你可以这样做是这样的:
b = Array.new(3) { [] }
这个不同的语法可以让你传递一个代码块,它为每个单元格运行来计算它的原始值。由于该块针对每个单元格运行,因此每次都会创建一个单独的数组。
不仅这个问题已经在[so]上被提出并回答了几十次,这个*确切的问题*,包括它的解决方案,在['Array :: new'] http://ruby-doc.org/core/Array.html#method-c-new-label-Common+gotchas)。 –
没有错误的问题,但有错误的答案。这是我的第一个问题。我已经为Ruby编了2天(编码40年),创建了一些类来处理任何游戏(自我训练)的游戏。这是我通过文档找不到的第一个问题(是的,我错过了文档中的某些东西 - 我确信这绝不会发生在你身上)。我确实搜索了“ruby + = push”,还有其他一些人试图在这里找不到任何东西。 Eiko的慷慨精神是一个很好的指导,@Jorg。我相信你是一个很好的“休闲程序员”,你不必通过拖动noobs来证明它。 –