Ruby嵌套for循环以填充数组数组

时间:2018-03-02 16:23:23

标签: ruby for-loop multidimensional-array

我试图通过编码康威的生命游戏来教自己Ruby。

我学习数组如何工作的初步步骤之一是创建一个Cell对象数组数组,定义如下:

class Cell
  def initialize(status, xpos, ypos)
    @status = status
    @position = [xpos,ypos]
  end
end

contents = Array.new(10, Array.new(10))

for i in 0..contents.length-1
  for j in 0..9
    contents.at(i).insert(j, Cell.new("DEAD", i, j))
  end
end

我希望<code>contents</code>是一个10号数组(就是这样),其中每个内部数组的大小也是10;但是每个内部阵列的最终大小为110,为什么会这样?

修改

所以看来我的主要问题是误解了插件是如何工作的。我将代码改为如下:

class Cell
  def initialize(status, xpos, ypos)
    @status = status
    @position = [xpos,ypos]
  end

  def declare_state
    puts "Position is [" + @position[0].to_s + ", " + @position[1].to_s + "] and status is " + @status
  end
end

contents = Array.new(10, Array.new(10))

for i in 0..9
  for j in 0..9
    contents[i][j] = Cell.new("DEAD", i, j))
  end
end

contents.each {
  |subarray| subarray.each {
    |cell| cell.declare_status
  }
}

看起来我所有Cell对象的所有@xpos值都设置为9,这是意料之外的。

3 个答案:

答案 0 :(得分:1)

我知道这并不直接相关,但解决这个问题的一种方法是使用each_with_index而不是嵌套for循环。它看起来像这样:

class Cell
    def initialize(status, xpos, ypos)
      @status = status
      @position = [xpos,ypos]
    end
end

contents = Array.new(10, Array.new(10))

contents.each_with_index do |row, row_index|
  row.each_with_index do |cell, cell_index|
    contents[row_index][cell_index] = Cell.new("DEAD", row_index, cell_index)
  end
end

答案 1 :(得分:0)

在行中:

contents = Array.new(10, Array.new(10))

创建一个包含10个位置的数组。您可能没有意识到的是,每个位置都填充了相同的数组。

我想你想要

contents = Array.new(10) { Array.new(10) }

答案 2 :(得分:0)

这里有两个问题。首先是你使用insert,它在子数组中创建新元素而不是编辑值。而不是contents.at(i).insert(j, cell)您可以使用contents[i][j] = cell,其中cell是您的单元格对象。

第二个问题是,您使用contents = Array.new(10, Array.new(10))创建了一个包含10个元素的数组,这些元素引用了相同的单个数组引用。如果对每个子数组运行object_id,您将看到它们都引用同一个对象。因此,更新其中一个子阵列似乎会更新所有子阵列。