Tablica wielowymiarowa Ruby

Może to tylko mój brak zdolności do znajdowania rzeczy tutaj jest problemem, ale nie mogę znaleźć nic o tym, jak tworzyć wielowymiarowe tablice w Ruby.

Mógłby mi ktoś podać przykład jak to zrobić?

Author: Bryan Ash, 2011-08-10

10 answers

Ściśle mówiąc nie jest możliwe tworzenie wielowymiarowych tablic w Rubim. Ale możliwe jest umieszczenie tablicy w innej tablicy, która jest prawie taka sama jak tablica wielowymiarowa.

Tak można utworzyć tablicę 2D w Rubim:

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


Jak wspomniano w komentarzach, możesz również użyć NArray, która jest biblioteką tablic numerycznych Ruby:
require 'narray'
b = NArray[ [1,2,3], [4,5,6], [7,8,9] ]

Użyj a[i][j], aby uzyskać dostęp do elementów tablicy. Zasadniczo a[i] zwraca ' sub array ' przechowywany na pozycji i z a i tym samym a[i][j] Zwraca numer elementu j z tablicy przechowywanej na pozycji i.

 39
Author: Veger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-28 20:27:03

Możesz przekazać blok do Array.new

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

Wartość zwracająca blok będzie wartością każdego indeksu pierwszej tablicy,

Więc..

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

I możesz uzyskać dostęp do tej tablicy za pomocą array[x][y]

Również dla instancji drugiej tablicy, można przekazać blok jako wartość domyślną. so

Array.new(2) { Array.new(3) { |index| index ** 2} } #=> [[0, 1, 4], [0, 1, 4]]
 22
Author: Orlando,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-15 16:55:38

Tylko Wyjaśnienie:

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

Nie jest wcale takie samo jak:

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

W późniejszym przypadku spróbuj:

arr[0][0] = 99

A oto co masz:

[[99,5], [99,5]]
 6
Author: Xavier Nayrac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-02 13:14:43

Metoda podana powyżej nie działa.

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

Jest równoważne

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]

I wyświetli 1.0, a nie 0.0, ponieważ modyfikujemy tablicę a i drukujemy element tablicy a.

 3
Author: kipar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-14 12:41:24

Istnieją dwa sposoby inicjalizacji wielu tablic (Rozmiar 2). Wszystkie inne odpowiedzi pokazują przykłady z wartością domyślną.

Declare each of sub-array (you can do it in a runtime):

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

Lub zadeklarować rozmiar tablicy nadrzędnej podczas inicjalizacji:

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

Przykład użycia:

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"

Więc możesz owinąć pierwszy sposób i użyć go w ten sposób:

@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
Author: Evmorov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-21 20:12:28

Musiałem niedawno odtworzyć wielowymiarową tablicę w stylu PHP w Rubim. Oto co zrobiłem:

# 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
Author: Damian Borowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-16 10:04:06

W rzeczywistości jest to znacznie szybsze niż metoda blokowa podana powyżej:

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

arr[0][1][2] += 1
 0
Author: Kri-ban,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-09 22:08:20

Być może możesz zasymulować swoją wielowymiarową tablicę za pomocą Hasha. Klucz Hashowy może być używany przez dowolny obiekt Ruby, więc można również pobrać tablicę.

Przykład:

marray = {}
p marray[[1,2]]   #-> nil
marray[[1,2]] = :a
p marray[[1,2]]   #-> :a

Na podstawie tego pomysłu można zdefiniować nową klasę.

Tylko szybki scenariusz:

=begin rdoc
Define a multidimensional array.

The keys must be Fixnum.

The following features from Array are not supported:
* negative keys (Like Array[-1])
* No methods <<, each, ...
=end
class MArray
  INFINITY = Float::INFINITY
=begin rdoc
=end
  def initialize(dimensions=2, *limits)
    @dimensions = dimensions
    raise ArgumentError if limits.size > dimensions
    @limits = []
    0.upto(@dimensions-1){|i|
      @limits << (limits[i] || INFINITY)
    }
    @content = {}
  end
  attr_reader :dimensions
  attr_reader :limits
=begin rdoc
=end
  def checkkeys(keys)
    raise ArgumentError, "Additional key values for %i-dimensional Array" % @dimensions if keys.size > @dimensions
    raise ArgumentError, "Missing key values for %i-dimensional Array" % @dimensions if keys.size != @dimensions
    raise ArgumentError, "No keys given" if keys.size == 0
    keys.each_with_index{|key,i|
      raise ArgumentError, "Exceeded limit for %i dimension" % (i+1) if key > @limits[i]
      raise ArgumentError, "Only positive numbers allowed" if key < 1

    }
  end
  def[]=(*keys)
    data = keys.pop
    checkkeys(keys)
    @content[keys] = data
  end
  def[](*keys)
    checkkeys(keys)
    @content[keys]
  end
end

Może być użyty jako:

arr = MArray.new()
arr[1,1] = 3
arr[2,2] = 3

Jeśli potrzebujesz predefiniowanej macierzy 2x2 możesz użyć jej jako:

arr = MArray.new(2,2,2)
arr[1,1] = 3
arr[2,2] = 3
#~ arr[3,2] = 3  #Exceeded limit for 1 dimension (ArgumentError)

Wyobrażam sobie, jak obsługiwać komendy typu << lub each w tablicy dwuwymiarowej, ale nie w wielowymiarowych.

 0
Author: knut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-21 20:34:49

Pomocne może być zapamiętanie, że tablica jest obiektem w Rubim, a obiekty nie są (domyślnie) tworzone po prostu przez nazwanie ich lub nazwanie odniesienia do obiektu. Oto procedura tworzenia tablicy 3 wymiarów i zrzucania jej do ekranu w celu weryfikacji:

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
 0
Author: mhdecoursey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-22 01:15:17

Oto Implementacja klasy tablicy 3D w Rubim, w tym przypadku domyślną wartością jest 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
Author: edymerchk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-13 15:48:14