我有一个数组数组,想要将元素追加到子数组中。 + =做我想要的,但我想理解为什么不推。
我期望的行为(和+ =一起使用):
b = Array.new(3,[])
b[0] += ["apple"]
b[1] += ["orange"]
b[2] += ["frog"]
b => [[“apple”],[“orange”],[“frog”]]
使用push我将push元素附加到EACH子数组(为什么?):
a = Array.new(3,[])
a[0].push("apple")
a[1].push("orange")
a[2].push("frog")
a => [[“apple”,“orange”,“frog”],[“apple”,“orange”,“frog”],[“apple”,“orange”,“frog”]]
对此的任何帮助都非常感谢。
答案 0 :(得分:10)
这里的问题是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] + = ["值"]有效?好吧,看看红宝石文档:
ary + other_ary→new_ary
Concatenation - 返回通过将两个数组连接在一起以生成第三个数组而构建的新数组。
[ 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) { [] }
这种不同的语法允许您传递一个代码块,该代码块为每个单元格运行以计算其原始值。由于为每个单元格运行块,因此每次都会创建一个单独的数组。
答案 1 :(得分:0)
这是因为在第二个代码部分,你选择了子阵列并推送到它,如果你想要一个阵列数组,你需要将阵列推到主阵列阵列。
a = Array.new(3,[])
a.push(["apple"])
a.push(["orange"])
a.push(["frog"])
获得与第一个相同的结果。
编辑:我忘了提及,因为你用空格数组初始化数组作为元素,你会在推送元素前面有三个空元素,