为什么两段代码都没有打印相同的东西。我打算让第一部分产生第二部分
的输出a=Array.new(5,Array.new(3))
for i in (0...a[0].length)
a[0][i]=2
end
p a
#the print [[2,2,2],[2,2,2],[2,2,2],[2,2,2],[2,2,2]] *
a=Array.new(5).map{|d|d=Array.new(3)}
for i in (0...a[0].length)
a[0][i]=2
end
p a
#the print [[2,2,2],[nil,nil,nil],[nil,nil,nil],[nil,nil,nil],[nil,nil,nil]]
答案 0 :(得分:3)
这一个
a=Array.new(5,Array.new(3))
创建一个包含相同数组对象的数组五次。这有点像这样:
a = []
b = a
a[0] = 123
puts b[0] #=> 123
这一个:
a=Array.new(5).map{ Array.new(3) }
为父数组中的每个项创建一个新的3项数组。因此,当您更改第一个项目时,它不会触及其他项目。
这也是为什么你不应该真正使用Array
和Hash
构造函数默认参数的原因,因为它们并不总是像你期望的那样工作。
答案 1 :(得分:1)
Array.new(5,Array.new(3))
在第一个示例中,您的数组包含对同一数组的5个引用。您可以使用Array.new(3)
创建一个数组的单个实例,该引用将用于初始化的5个数组中的每个数组。修改a[0][0]
时,您还要修改a[1][0]
,a[2][0]
等。它们都是对同一数组的引用。
Array.new(5).map{ |d| Array.new(3) }
在第二个示例中,您的数组包含5个不同的数组。您的块被调用5次,Array.new(3)
被调用5次,并且创建了5个不同的数组。 a[0]
是与a[1]
等不同的数组
答案 2 :(得分:1)
以下是等效的:
Array.new(5,Array.new(3))
[Array.new(3)] * 5
inside = Array.new(3); [inside, inside, inside, inside, inside]
它们都将生成包含相同数组的数组。我的意思是完全相同的对象。这就是为什么如果你修改它的内容,你会看到新值5次。
如果需要独立数组,您需要确保“内部”数组不是同一个对象。这可以通过不同方式实现,例如:
Array.new(5){ Array.new(3) }
5.times.map { Array.new(3) }
Array.new(5).map { Array.new(3) }
# or dup your array manually:
inside = Array.new(3); [inside.dup, inside.dup, inside.dup, inside.dup, inside]
请注意,您首先使用的Array.new(5, [])
表单不会为您复制obj
,它会重复使用它。由于这不是您想要的,您应该使用块形式Array.new(5){ [] }
,它将调用块5次,并且每次创建一个新数组。
Hash
类还有两个构造函数,even more tricky。