En Ruby, étant donné un tableau sous l'une des formes suivantes...
[apple, 1, banana, 2]
[[apple, 1], [banana, 2]]
...quelle est la meilleure façon de convertir ceci en un hash sous la forme de...
{apple => 1, banana => 2}
En Ruby, étant donné un tableau sous l'une des formes suivantes...
[apple, 1, banana, 2]
[[apple, 1], [banana, 2]]
...quelle est la meilleure façon de convertir ceci en un hash sous la forme de...
{apple => 1, banana => 2}
Il suffit d'utiliser Hash[*array_variable.flatten]
Par exemple :
a1 = ['apple', 1, 'banana', 2]
h1 = Hash[*a1.flatten(1)]
puts "h1: #{h1.inspect}"
a2 = [['apple', 1], ['banana', 2]]
h2 = Hash[*a2.flatten(1)]
puts "h2: #{h2.inspect}"
Utilisation Array#flatten(1)
limite la récursivité de telle sorte que Array
Les clés et les valeurs fonctionnent comme prévu.
AVERTISSEMENT : les réponses utilisant flatten poseront des problèmes si vous voulez des clés ou des valeurs de type tableau.
J'ai publié ci-dessous une solution alternative qui évitera les problèmes liés aux clés ou aux valeurs des tableaux.
NOTE : Pour une solution concise et efficace, voir Réponse de Marc-André Lafortune ci-dessous.
Cette réponse a été proposée à l'origine comme une alternative aux approches utilisant flatten, qui étaient les plus votées au moment de la rédaction. J'aurais dû préciser que je n'avais pas l'intention de présenter cet exemple comme une meilleure pratique ou une approche efficace. La réponse originale suit.
Attention ! Solutions utilisant aplatir ne préservera pas les clés ou les valeurs des tableaux !
En nous appuyant sur la réponse populaire de @John Topley, essayons :
a3 = [ ['apple', 1], ['banana', 2], [['orange','seedless'], 3] ]
h3 = Hash[*a3.flatten]
Cela provoque une erreur :
ArgumentError: odd number of arguments for Hash
from (irb):10:in `[]'
from (irb):10
Le constructeur attendait un tableau de longueur égale (par exemple ['k1','v1,'k2','v2']). Ce qui est pire, c'est qu'un tableau différent qui s'aplatirait à une longueur paire nous donnerait silencieusement un Hash avec des valeurs incorrectes.
Si vous souhaitez utiliser des clés ou des valeurs de type tableau, vous pouvez utiliser la fonction carte :
h3 = Hash[a3.map {|key, value| [key, value]}]
puts "h3: #{h3.inspect}"
Cela permet de conserver la clé du tableau :
h3: {["orange", "seedless"]=>3, "apple"=>1, "banana"=>2}
C'est la même chose que Hash[a3], puisque a3 == a3.map{|k,v| [k,v]} est vrai, c'est en fait l'équivalent de a3.dup.
Au lieu d'utiliser map, pourquoi ne pas simplement spécifier la profondeur de l'aplatissement ? Par exemple : h3 = Hash[*a3.flatten(1)]
au lieu de h3 = Hash[*a3.flatten]
ce qui provoquerait une erreur.
La meilleure façon est d'utiliser Array#to_h
:
[ [:apple,1],[:banana,2] ].to_h #=> {apple: 1, banana: 2}
Il convient de noter que to_h
accepte également un bloc :
[:apple, :banana].to_h { |fruit| [fruit, "I like #{fruit}s"] }
# => {apple: "I like apples", banana: "I like bananas"}
Note : to_h
accepte un bloc en Ruby 2.6.0+ ; pour les premiers Ruby, vous pouvez utiliser mon fichier backports
gemme et require 'backports/2.6.0/enumerable/to_h'
to_h
sans bloc a été introduite dans Ruby 2.1.0.
Avant Ruby 2.1, on pouvait utiliser la formule moins lisible Hash[]
:
array = [ [:apple,1],[:banana,2] ]
Hash[ array ] #= > {:apple => 1, :banana => 2}
Enfin, il faut se méfier des solutions qui utilisent flatten
Cela pourrait créer des problèmes avec les valeurs qui sont elles-mêmes des tableaux.
J'aime la to_h
est meilleure que les réponses précédentes, car elle exprime l'intention de convertir les après opérant sur le tableau.
Mise à jour
Ruby 2.1.0 est disponible aujourd'hui . Et je viens avec Array#to_h
( notes de mise à jour et ruby-doc ), ce qui résout le problème de la conversion d'un fichier Array
à un Hash
.
Exemple de documentation Ruby :
[[:foo, :bar], [1, 2]].to_h # => {:foo => :bar, 1 => 2}
Ceci mais voici une façon de convertir un tableau en hachage :
require "enumerator"
class Array
def to_h
Hash[*enum_with_index.to_a.flatten]
end
end
%w{a b c d}.to_h # => {"a"=>0, "b"=>1, "c"=>2, "d"=>3}
Autre exemple :
["foo", "bar", "foo1", "bar1","foo2", "bar2"] convert to
{"foo"=>"bar", "foo1"=>"bar1","foo2"=>"bar2"}
def array_to_hash(array)
count = 0
hash = Hash.new
(array.length / 2).times do
hash[array[count]] = array[count+1]
count += 2
end
return hash
end
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.