在ruby中,这是一个二维数组错误吗?

时间:2017-12-12 19:19:25

标签: ruby

我有一个方法:

def test
    f = Array.new(4,Array.new(4,false))
    f.each do |array|
        p array.inspect
    end
    f[1][1] = true
    p "after setting f[1][1]"
    f.each do |array|
        p array.inspect
    end
end

这是输出:

"[false, false, false, false]"
"[false, false, false, false]"
"[false, false, false, false]"
"[false, false, false, false]"
"after setting f[1][1]"
"[false, true, false, false]"
"[false, true, false, false]"
"[false, true, false, false]"
"[false, true, false, false]"

正如你可以看到col 1中的所有值都变为true,为什么会发生这种情况?

1 个答案:

答案 0 :(得分:1)

这不是一个错误。 Array.new(4, Array.new(4,false))创建一个包含4个元素的数组,其中每个元素都是由单个Array.new(4, false)调用确定的相同的数组对象。对于Array.new(4,false)的每个元素,它不执行f 4次,一次。因此,您最终得到f作为对同一对象的4个引用的数组(单个4元素数组,[false, false, false, false])。

如果你想拥有一个包含4个不同4元素数组的数组,那么在Ruby中有很多方法可以做到这一点。一种方法是:

f = Array.new(4) { Array.new(4, false) }

这将针对Array.new(4, false)中的每个条目单独执行Array.new(4)

2.4.0 :002 >  f = Array.new(4) { Array.new(4, false) }
 => [[false, false, false, false], [false, false, false, false], [false, false, false, false], [false, false, false, false]]
2.4.0 :003 > f.each do |array|
2.4.0 :004 >   p array.inspect
2.4.0 :005?> end
"[false, false, false, false]"
"[false, false, false, false]"
"[false, false, false, false]"
"[false, false, false, false]"
 => [[false, false, false, false], [false, false, false, false], [false, false, false, false], [false, false, false, false]]
2.4.0 :006 > f[1][1] = true
 => true
2.4.0 :007 > p "after setting f[1][1]"
"after setting f[1][1]"
 => "after setting f[1][1]"
2.4.0 :008 > f.each do |array|
2.4.0 :009 >   p array.inspect
2.4.0 :010?> end
"[false, false, false, false]"
"[false, true, false, false]"
"[false, false, false, false]"
"[false, false, false, false]"
 => [[false, false, false, false], [false, true, false, false], [false, false, false, false], [false, false, false, false]]
2.4.0 :011 >

供参考,请参阅Creating Arrays
文档。