Как объявить двумерный массив в Ruby
мне нужен двумерный массив в Ruby, к которому я могу получить доступ, например, так:
if @array[x][y] == "1" then @array[x][y] = "0"
проблема в том, что я не знаю начальных размеров размеров массива, и я выращиваю массив (с помощью <<
оператор).
как объявить его как переменную экземпляра, поэтому я не получаю такой ошибки?
undefined method `[]' for nil:NilClass (NoMethodError)
ВОПРОС ОБНОВЛЕН:
@array = Array.new {Array.new}
теперь работает для меня, поэтому комментарий от Мэтта ниже Правильный!
I просто выяснил, почему я получил ошибку, потому что я повторял массив следующим образом:
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 ответов
простая реализация для разреженного 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
комментарий Мэтта на ваш вопрос совершенно правильный. Однако, основываясь на том, что вы пометили это "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.
Рубин Array
не дает вам этой возможности.
либо вы делаете это вручную:
(@array[x] ||= [])[y] = 42
или вы используете хэш:
@hash = Hash.new{|h, k| h[k] = []}
@hash[42][3] = 42
@hash # => {42 => [nil, nil, nil, 42]}