红宝石中的数组数组,通过引用传递

时间:2011-12-03 12:18:34

标签: ruby arrays reference

我正在尝试在Ruby中创建一个充满零的5x5矩阵。我使用的代码是:

ruby-1.9.2-p290 :014 > a = Array.new(5, Array.new(5, 0))
 => [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] 

但是,新创建的数组不是单独的对象,而是对一个对象的引用。因此,当我尝试执行以下操作时:a[2][2] = 1我得到:

=> [[0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]] 

这显然不是我想要的。检查对象ID确认它:

ruby-1.9.2-p290 :020 > a.collect {|z| z.__id__}.uniq
 => [70253724580020] 

我的问题是:它是一个错误或功能吗? :)我应该如何正确创建数组?

2 个答案:

答案 0 :(得分:7)

  

我正在尝试在Ruby中创建一个充满零的5x5矩阵。我使用的代码是:

正如其他人所指出的,这就是数组应该如何工作的方式。相反,您应该使用块初始化程序:

a = Array.new(5) { Array.new(5, 0) }

此外,如果您正在制作矩阵,请考虑使用标准库中的Matrix类

require 'matrix'
 # => true 

m = Matrix.build(5, 5) { 0 }
 # => Matrix[[0, 0, 0, 0, 0],
 #           [0, 0, 0, 0, 0],
 #           [0, 0, 0, 0, 0],
 #           [0, 0, 0, 0, 0],
 #           [0, 0, 0, 0, 0]] 

m.determinant
 # => 0 

答案 1 :(得分:5)

实际上它是feature

  

[...]它是使用大小 obj 的副本创建的(即 size 引用   到同一个 obj )[...]

要创建不同的数组,您可以使用例如

a = Array.new(5){Array.new(5, 0)}

a = (1..5).map{Array.new(5, 0)}