使用`Array.new(n,Array.new)`创建矩阵

时间:2014-03-14 22:42:33

标签: ruby arrays

我通过执行以下操作创建了一个数组:

@gameboard = Array.new(3, Array.new(3, " "))

我尝试分配这样的值,我得到了这个:

@gameboard[0][2] = "X"
@gameboard #=> [[" ", " ", "X"], [" ", " ", "X"], [" ", " ", "X"]]

当我以不同方式声明数组时,

@gameboard = [[" ", " ", " "], [" ", " ", " "], [" ", " ", " "]]

我得到了这个结果:

@gameboard[0][2] = "X"
@gameboard # => [[" ", " ", "X"], [" ", " ", " "], [" ", " ", " "]]

为数组分配值时,为什么使用Array.new方法会产生不同的行为?

2 个答案:

答案 0 :(得分:7)

按照代码:

@gameboard = Array.new(3, Array.new(3, " "))
@gameboard.map { |a| a.object_id }
# => [76584030, 76584030, 76584030]

表示new(size=0, obj=nil)方法创建一个size数组,具有相同的ob

new(size) {|index| block }方法以不同的方式工作;它创建了一个size数组,具有不同的obs

请参阅以下代码:

@gameboard = Array.new(3) { Array.new(3, " ") }
@gameboard.map { |a| a.object_id }
# => [75510080, 75509920, 75509540]

以上内容与您的第二个代码示例相同:

@gameboard = [[" ", " ", " "], [" ", " ", " "], [" ", " ", " "]]
@gameboard.map { |a| a.object_id }
# => [80194090, 80193400, 80193080]

如果更改或更新1的第一个元素数组的索引@gameboard处的值,则不会影响所有其他内部数组元素。

@gameboard = Array.new(3) { Array.new(3, " ") }
@gameboard[0][1] = 2
@gameboard
# => [[" ", 2, " "], [" ", " ", " "], [" ", " ", " "]]

答案 1 :(得分:1)

Array constructor不会复制您传递的对象;它将重用该对象来填充数组。

使用块表单为每个索引创建一个新对象:

@gameboard = Array.new(3) { |i| Array.new(3) { |j| " " } }