修改 Ruby 二维数组

4
如果我创建了这个数组:
a = Array.new(3,Array.new(2,0))

它创造了:

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

当我尝试更改特定元素时:

a[0][0] = 3

IT技术可以同时改变多个值:

 => [[3, 0], [3, 0], [3, 0]]

为什么会发生这种情况?如何更改特定元素?
2个回答

6

你需要更改数组的初始化方式 (这是一个已知的问题),将其修改为:

a = Array.new(3) { Array.new(2,0) }

您的版本和此版本的区别在于Array.new(2,0)只出现一次。您正在创建一个包含3个指向第二个数组的“指针”的数组。您可以在以下代码中看到这一点的演示:
a = Array.new(3,Array.new(2,0))
a.map { |a| a.object_id }
#=> [70246027840960, 70246027840960, 70246027840960] # Same object ids!

a = Array.new(3) { Array.new(2,0) }
a.map { |a| a.object_id }
#=> [70246028007600, 70246028007580, 70246028007560] # Different object ids

如果默认值是不可变的,例如Fixnum,则这样做是可以的。如果a = Array.new(3) { Array.new(2,'a') }a是可变的),并且您重新分配一个元素,a[0][0] = 'b',那么没有问题:a #=> [["b","a"], ["a","a"], ["a","a"]]。但是,如果您替换一个元素,a[0][0].replace('b'),则会得到[["b","b"], ["a","a"], ["a", "a"]]。(如果您想测试此内容,请确保首先重新初始化a。)如果您使用a = Array.new(3) { Array.new(2) {'a'} },然后a[0][0].replace('b'); a #=> [["b","a"], ["a","a"], ["a","a"]],就像期望的一样。如果您不确定,请将默认值放在块中。 - Cary Swoveland

4

您可能需要参考这里

Array.new(3,Array.new(2,0))可以分为两步理解:

  1. 创建一个新的数组Array.new(2,0)

  2. 再创建一个新的数组,其中有3个元素,每个元素都是同一个对象(1)。

因此,在任何子数组中更改值都会更改所有子数组中的值。子数组引用同一对象。

正如Gavin Miller指出的那样,您需要使用a = Array.new(3) { Array.new(2,0) }来更改每个元素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接