Как объявить двумерный массив в Ruby - PullRequest
7 голосов
/ 05 февраля 2012

Мне нужен двумерный массив в Ruby, к которому я могу получить доступ, например, так:

if @array[x][y] == "1" then @array[x][y] = "0"

Проблема в том, что я не знаю начальных размеров размеров массива и увеличиваю массив (с помощью оператора <<).

Как мне объявить его как переменную экземпляра, чтобы я не получил такую ​​ошибку?

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

ВОПРОС ОБНОВЛЕНО:

@array = Array.new {Array.new} 

теперь работает для меня, поэтому комментарий Мэтта ниже верен!

Я только что узнал, почему я получил ошибку, потому что я перебрал массив так:

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] ...

Ответы [ 3 ]

7 голосов
/ 05 февраля 2012

Простая реализация разреженного 2-мерного массива с использованием вложенных хешей,

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
5 голосов
/ 05 февраля 2012

Комментарий Мэтта к вашему вопросу абсолютно верен.Однако, основываясь на том факте, что вы пометили эту «игру-жизнь», похоже, вы пытаетесь инициализировать двумерный массив, а затем использовать это в вычислениях для игры.Если вы хотите сделать это в Ruby, один из способов сделать это будет:

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

, который создаст массив my_x_size * my_y_size, заполненный нулями.

Этот код создает новый массив вашего размера x, затем инициализирует каждый элемент этого массива как другой массив вашего размера y и инициализирует каждый элемент каждого второго массива нулями.

3 голосов
/ 05 февраля 2012

Ruby's Array не дает вам этой функциональности.

Либо вы делаете это вручную:

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

Или вы используете хэши:

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