如何在Ruby中声明一个二维数组

7
我希望在Ruby中获得一个二维数组,我可以像这样访问它:
if @array[x][y] == "1" then @array[x][y] = "0"

问题是:我不知道数组维度的初始大小,我使用 << 操作符来扩展数组。

我如何将其声明为实例变量,以便不会出现此类错误?

undefined method `[]' for nil:NilClass (NoMethodError)

QUESTION UPDATED:

@array = Array.new {Array.new} 

现在对我来说已经可以工作了,因此Matt下面的评论是正确的!

我刚刚发现我收到错误的原因是因为我像这样迭代了数组:

for i in 0..@array.length
    for j in 0..@array[0].length
        @array[i][j] ...

显然是错误的并引发了错误。它应该像这样:

for i in 0..@array.length-1
        for j in 0..@array[0].length-1
            @array[i][j] ...

6
Ruby采用动态类型--因此你不需要事先“声明”一个变量是二维数组。你可以创建一个变量并将其初始化为一个数组。然后开始在其中放置数组。 - Matt Fenwick
对于 array = Array.new {Array.new},需要改为 array = Array.new(3) {Array.new(2)},需要在括号内加入数字。 - asdjkag
3个回答

7
使用嵌套哈希表实现稀疏二维数组的简单方法,
class SparseArray
  attr_reader :hash

  def initialize
    @hash = {}
  end

  def [](key)
    hash[key] ||= {}
  end

  def rows
    hash.length   
  end

  alias_method :length, :rows
end

使用方法:

sparse_array = SparseArray.new
sparse_array[1][2] = 3
sparse_array[1][2] #=> 3

p sparse_array.hash
#=> {1=>{2=>3}}

#
# dimensions
#
sparse_array.length    #=> 1
sparse_array.rows      #=> 1

sparse_array[0].length #=> 0
sparse_array[1].length #=> 1

1
你可以通过向 fetch 提供一个块来避免使用 rescue: hash.fetch(key){ hash[key] = {} } 会更快。此外,hash[key] ||= {} 更短且更常用。 - Marc-André Lafortune
@Marc-AndréLafortune:已经注意到了 :-). 获取和救援是不必要的。 - jcsherin
每个维度都有一个 .length 方法是可能的吗? - kadrian
@ka2011r:是的,请查看更新后的代码。此外,您还可以混入Enumerable模块并覆盖#each以获得更多功能。 - jcsherin

5

Matt先生对你的问题的评论完全正确。但是,根据你标记的"conways-game-of-life",似乎你正在尝试初始化一个二维数组,然后在游戏计算中使用它。如果你想在Ruby中实现这个功能,可以这样做:

a = Array.new(my_x_size) { |i| Array.new(my_y_size) { |i| 0 }}

这段代码将创建一个大小为my_x_size * my_y_size的数组,并将其填充为零。

这段代码的作用是创建一个新的大小为x的数组,然后将该数组的每个元素初始化为另一个大小为y的数组,并将第二个数组的每个元素都初始化为0。


3

Ruby的Array并不提供这个功能。

你可以手动实现:

(@array[x] ||= [])[y] = 42

或者您可以使用哈希:

@hash = Hash.new{|h, k| h[k] = []}
@hash[42][3] = 42
@hash # => {42 => [nil, nil, nil, 42]}

1
我采用了你使用哈希表来编写SparseArray的想法。在《Ruby Way》一书中,还有一个使用哈希表的示例实现。 - jcsherin

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