C'est peut-être le problème qui vient de mon manque de capacité à trouver des éléments ici, mais je ne trouve rien sur la création de tableaux multidimensionnels dans Ruby.
Quelqu'un pourrait-il s'il vous plaît me donner un exemple sur la façon de le faire?
Strictement parlant, il n’est pas possible de créer des tableaux multidimensionnels en Ruby. Mais il est possible de placer un tableau dans un autre tableau, qui est presque identique à un tableau multidimensionnel.
Voici comment créer un tableau 2D en Ruby:
a = [[1,2,3], [4,5,6], [7,8,9]]
require 'narray'
b = NArray[ [1,2,3], [4,5,6], [7,8,9] ]
Utilisez a[i][j]
pour accéder aux éléments du tableau. De manière générale, a[i]
renvoie le "sous-tableau" stocké à la position i
sur a
. Ainsi, a[i][j]
renvoie le numéro d'élément j
à partir du tableau stocké à la position i
.
vous pouvez passer un bloc à Array.new
Array.new(n) {Array.new(n,default_value)}
la valeur qui retourne le bloc sera la valeur de chaque index du premier tableau,
alors..
Array.new(2) {Array.new(2,5)} #=> [[5,5],[5,5]]
et vous pouvez accéder à ce tableau en utilisant array[x][y]
également pour la deuxième instanciation de tableau, vous pouvez également passer un bloc comme valeur par défaut. alors
Array.new(2) { Array.new(3) { |index| index ** 2} } #=> [[0, 1, 4], [0, 1, 4]]
Juste une clarification:
arr = Array.new(2) {Array.new(2,5)} #=> [[5,5],[5,5]]
n'est pas du tout la même chose que:
arr = Array.new(2, Array.new(2, 5))
dans le dernier cas, essayez:
arr[0][0] = 99
et voici ce que vous avez:
[[99,5], [99,5]]
La méthode donnée ci-dessus ne fonctionne pas.
n = 10
arr = Array.new(n, Array.new(n, Array.new(n,0.0)))
arr[0][1][2] += 1
puts arr[0][2][2]
est équivalent à
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]
et affichera 1.0, pas 0.0, car nous modifions le tableau a et imprimons l’élément du tableau a.
Il existe deux façons d’initialiser un tableau multiple (taille de 2) . Toutes les autres réponses montrent des exemples avec une valeur par défaut.
Déclarez chaque sous-tableau (vous pouvez le faire dans un runtime):
multi = []
multi[0] = []
multi[1] = []
ou déclarer la taille d'un tableau parent lors de l'initialisation:
multi = Array.new(2) { Array.new }
Exemple d'utilisation:
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"
Donc, vous pouvez envelopper la première manière et l'utiliser comme ceci:
@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"
J'ai dû reproduire récemment un tableau multidimensionnel de style PHP dans Ruby. Voici ce que j'ai fait:
# 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
En réalité, cela est beaucoup plus rapide que la méthode de bloc donnée ci-dessus:
arr = Array.new(n, Array.new(n, Array.new(n,0.0)))
arr[0][1][2] += 1
Voici une implémentation d'une classe de tableau 3D en Ruby, dans ce cas la valeur par défaut est 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
Il peut être utile de se rappeler que le tableau est un objet dans Ruby et que les objets ne sont pas (par défaut) créés simplement en les nommant ou en nommant la référence à l'objet. Voici une routine pour créer un tableau à 3 dimensions et le vider à l'écran pour vérification:
def Create3DimensionArray (x, y, z, valeur par défaut) n = 0 # code de vérification uniquement ar = Array.new (x) pour i en 0 ... x ar [i] = Array.new (y) pour j dans 0 ... y ar [i] [j] = Array.new (z, par défaut) pour k dans 0 ... z # code de vérification uniquement ar [i] [j] [k] = n # code de vérification uniquement n + = 1 # code de vérification uniquement fin # code de vérification seulement fin fin return ar end # Crée un échantillon et vérifie ar = Create3DimensionArray (3, 7, 10, 0) pour x dans ar met "||" pour y dans x met "|" pour z dans y printf "% d", z fin fin fin
Peut-être que vous pouvez simuler votre tableau multidimensionnel avec un hachage. La clé de hachage peut être utilisée par n'importe quel objet Ruby, vous pouvez donc aussi prendre un tableau.
Exemple:
marray = {}
p marray[[1,2]] #-> nil
marray[[1,2]] = :a
p marray[[1,2]] #-> :a
Sur la base de cette idée, vous pouvez définir une nouvelle classe.
Juste un scénario rapide:
=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
Ceci peut être utilisé comme:
arr = MArray.new()
arr[1,1] = 3
arr[2,2] = 3
Si vous avez besoin d'une matrice 2x2 prédéfinie, vous pouvez l'utiliser comme:
arr = MArray.new(2,2,2)
arr[1,1] = 3
arr[2,2] = 3
#~ arr[3,2] = 3 #Exceeded limit for 1 dimension (ArgumentError)
Je pourrais imaginer comment gérer des commandes telles que <<
ou each
dans un tableau à deux dimensions, mais pas dans des tableaux à plusieurs dimensions.