Рубиновый многомерный массив - PullRequest
43 голосов
/ 10 августа 2011

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

Может кто-нибудь дать мне пример того, каксделать это?

Ответы [ 11 ]

41 голосов
/ 10 августа 2011

Строго говоря, в Ruby невозможно создавать многомерные массивы. Но можно поместить массив в другой массив, который почти совпадает с многомерным массивом.

Вот как вы можете создать 2D-массив в Ruby:

a = [[1,2,3], [4,5,6], [7,8,9]]

<ч /> Как указано в комментариях, вы также можете использовать NArray , который представляет собой библиотеку числовых массивов Ruby:

require 'narray'
b = NArray[ [1,2,3], [4,5,6], [7,8,9] ]
<Ч />

Используйте a[i][j] для доступа к элементам массива. В основном a[i] возвращает «подмассив», сохраненный в позиции i из a, и, таким образом, a[i][j] возвращает номер элемента j из массива, который хранится в позиции i.

22 голосов
/ 05 февраля 2013

Вы можете передать блок на Array.new

Array.new(n) {Array.new(n,default_value)}

значение, которое возвращает блок, будет значением каждого индекса первого массива,

так ..

Array.new(2) {Array.new(2,5)} #=> [[5,5],[5,5]]

и вы можете получить доступ к этому массиву, используя array[x][y]

также для второго создания массива, вы также можете передать блок как значение по умолчанию. так

Array.new(2) { Array.new(3) { |index| index ** 2} } #=> [[0, 1, 4], [0, 1, 4]]
7 голосов
/ 02 января 2015

Просто уточнение:

arr = Array.new(2) {Array.new(2,5)} #=> [[5,5],[5,5]]

совсем не совпадает с:

arr = Array.new(2, Array.new(2, 5))

в последнем случае попробуйте:

arr[0][0] = 99

и вот что вы получили:

[[99,5], [99,5]]
5 голосов
/ 21 февраля 2015

Существует два способа инициализации мультимассива (размер 2). Все остальные ответы показывают примеры со значением по умолчанию.

Объявите каждый из подмассива (вы можете сделать это во время выполнения):

multi = []
multi[0] = []
multi[1] = []

или объявляйте размер родительского массива при инициализации:

multi = Array.new(2) { Array.new }

Пример использования:

multi[0][0] = 'a'
multi[0][1] = 'b'
multi[1][0] = 'c'
multi[1][1] = 'd'

p multi # [["a", "b"], ["c", "d"]]
p multi[1][0] # "c"

Так что вы можете обернуть первый способ и использовать его так:

@multi = []
def multi(x, y, value)
  @multi[x] ||= []
  @multi[x][y] = value
end

multi(0, 0, 'a')
multi(0, 1, 'b')
multi(1, 0, 'c')
multi(1, 1, 'd')

p @multi # [["a", "b"], ["c", "d"]]
p @multi[1][0] # "c"
3 голосов
/ 14 июня 2013

Приведенный выше метод не работает.

n = 10
arr = Array.new(n, Array.new(n, Array.new(n,0.0))) 
arr[0][1][2] += 1
puts arr[0][2][2]

эквивалентно

n = 10
a = Array.new(n,0.0)
b = Array.new(n,a)
arr = Array.new(n, b) 
arr[0][1][2] += 1
puts arr[0][2][2]

и выведет 1.0, а не 0.0, потому что мы модифицируем массив a и печатаем элемент массива a.

1 голос
/ 16 февраля 2016

Недавно мне пришлось воспроизводить многомерный массив в стиле PHP в Ruby.Вот что я сделал:

# Produce PHP-style multidimensional array.
#
# Example
#
# arr = Marray.new
#
# arr[1][2][3] = "foo"
# => "foo"
#
# arr[1][2][3]
# => "foo"

class Marray < Array
  def [](i)
    super.nil? ? self[i] = Marray.new : super
  end
end
1 голос
/ 10 марта 2013

На самом деле это намного быстрее, чем метод блока, приведенный выше:

arr = Array.new(n, Array.new(n, Array.new(n,0.0))) 

arr[0][1][2] += 1
0 голосов
/ 15 июля 2019

Использование также можно использовать Gem XKeys.

require 'xkeys'

regular = [].extend XKeys::Auto
regular[1,2,3] = 4
# [nil, [nil, nil, [nil, nil, nil, 4]]]
regular[3,2,1, :else=>0] # 0
# Note: regular[1,2] is a slice
# Use regular[1,2,{}] to access regular[1][2]

sparse = {}.extend XKeys::Hash
sparse[1,2,3] = 4
# {1=>{2=>{3=>4}}}
path=[1,2,3]
sparse[*path,{}] # 4
0 голосов
/ 13 июля 2016

Вот реализация класса трехмерного массива в ruby, в данном случае значение по умолчанию 0

class Array3
 def initialize
   @store = [[[]]]
 end

 def [](a,b,c)
  if @store[a]==nil ||
    @store[a][b]==nil ||
    @store[a][b][c]==nil
   return 0
  else
   return @store[a][b][c]
  end
 end

 def []=(a,b,c,x)
  @store[a] = [[]] if @store[a]==nil
  @store[a][b] = [] if @store[a][b]==nil
  @store[a][b][c] = x
 end
end


array = Array3.new
array[1,2,3] = 4
puts array[1,2,3] # => 4
puts array[1,1,1] # => 0
0 голосов
/ 22 декабря 2015

Может быть полезно помнить, что массив является объектом в ruby, и объекты не (по умолчанию) создаются просто путем присвоения им имен или ссылки на объект.Вот процедура для создания трехмерного массива и вывода его на экран для проверки:

def Create3DimensionArray(x, y, z, default)
    n = 0                       # verification code only
    ar = Array.new(x)
    for i in 0...x
        ar[i] = Array.new(y)
        for j in 0...y
            ar[i][j] = Array.new(z, default)
            for k in 0...z      # verification code only
                ar[i][j][k] = n # verification code only
                n += 1          # verification code only
            end                 # verification code only
        end
    end
    return ar
end

# Create sample and verify
ar = Create3DimensionArray(3, 7, 10, 0)

for x in ar
    puts "||"
    for y in x
        puts "|"
        for z in y
            printf "%d ", z
        end
    end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...