Je me demande s’il est possible de créer un tableau à deux dimensions et d’accéder rapidement à tout sous-tableau horizontal ou vertical qu’il contient.
Je crois que nous pouvons accéder à un sous-tableau horizontal dans le cas suivant:
x = Array.new(10) { Array.new(20) }
x[6][3..8] = 'something'
Mais pour autant que je sache, nous ne pouvons pas y accéder comme ceci:
x[3..8][6]
Comment puis-je éviter ou pirater cette limite?
Il y a quelques problèmes avec 2 dimensions Arrays
la façon dont vous les implémentez.
a= [[1,2],[3,4]]
a[0][2]= 5 # works
a[2][0]= 6 # error
Hash
comme Array
Je préfère utiliser Hashes
pour plusieurs dimensions Arrays
a= Hash.new
a[[1,2]]= 23
a[[5,6]]= 42
Cela présente l'avantage que vous n'avez pas à créer manuellement des colonnes ou des lignes. L'insertion dans les hachages est presque O (1) , il n'y a donc aucun inconvénient ici, tant que votre Hash
ne devient pas trop gros.
Vous pouvez même définir une valeur par défaut pour tous les éléments non spécifiés
a= Hash.new(0)
Alors maintenant, sur la façon d'obtenir des sous-tableaux
(3..5).to_a.product([2]).collect { |index| a[index] }
[2].product((3..5).to_a).collect { |index| a[index] }
(a..b).to_a
s'exécute en O (n). Récupérer un élément d'un Hash
équivaut presque à O (1), ainsi la collecte s'exécute presque en O (n). Il n'y a aucun moyen de le rendre plus rapide que O (n), car copier n éléments est toujours O (n).
Hashes
peut avoir des problèmes quand ils deviennent trop gros. Je réfléchirais donc à deux fois avant de mettre en œuvre un Array
multidimensionnel comme celui-ci, si je savais que ma quantité de données grossissait.
rows, cols = x,y # your values
grid = Array.new(rows) { Array.new(cols) }
En ce qui concerne l'accès aux éléments, cet article est très utile pour une méthode pas à pas d'encapsuler un tableau comme vous le souhaitez:
Vous n'avez pas indiqué votre objectif réel, mais peut-être que cela peut aider:
require 'matrix' # bundled with Ruby
m = Matrix[
[1, 2, 3],
[4, 5, 6]
]
m.column(0) # ==> Vector[1, 4]
(et les vecteurs agissent comme des tableaux)
ou, en utilisant une notation similaire à celle que vous désirez:
m.minor(0..1, 2..2) # => Matrix[[3], [6]]
Voici un cas de tableau 3D
class Array3D
def initialize(d1,d2,d3)
@data = Array.new(d1) { Array.new(d2) { Array.new(d3) } }
end
def [](x, y, z)
@data[x][y][z]
end
def []=(x, y, z, value)
@data[x][y][z] = value
end
end
Vous pouvez accéder aux sous-sections de chaque tableau comme n'importe quel autre Ruby tableau. @Data [0..2] [3..5] [8..10] = 0 etc.
x.transpose[6][3..8]
ou x[3..8].map {|r| r [6]}
donnerais ce que tu veux.
Exemple:
a = [ [1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[21, 22, 23, 24, 25]
]
#a[1..2][2] -> [8,13]
puts a.transpose[2][1..2].inspect # [8,13]
puts a[1..2].map {|r| r[2]}.inspect # [8,13]
Je suis assez sûr que cela peut être très simple
2.0.0p247 :032 > list = Array.new(5)
=> [nil, nil, nil, nil, nil]
2.0.0p247 :033 > list.map!{ |x| x = [0] }
=> [[0], [0], [0], [0], [0]]
2.0.0p247 :034 > list[0][0]
=> 0
a = Array.new(Array.new(4))
0.upto(a.length-1) do |i|
0.upto(a.length-1) do |j|
a[i[j]] = 1
end
end
0.upto(a.length-1) do |i|
0.upto(a.length-1) do |j|
print a[i[j]] = 1 #It's not a[i][j], but a[i[j]]
end
puts "\n"
end