40 votes

Comment initialiser un Array à l'intérieur d'un Hash en Ruby ?

J'essaie d'initialiser un hachage de tableaux comme suit

@my_hash = Hash.new(Array.new)

pour que je puisse :

@my_hash["hello"].push("in the street")
=> ["in the street"]
@my_hash["hello"].push("at home")
=> ["in the street", "at home"]
@my_hash["hello"]
=>["in the street", "at home"]

Le problème est que toute nouvelle clé de hachage renvoie également ["in the street", "at home"]

@my_hash["bye"]
=> ["in the street", "at home"]
@my_hash["xxx"]
=> ["in the street", "at home"]

! !!???

Qu'est-ce que je fais de travers ? Quelle serait la bonne façon d'initialiser un hachage de tableaux ?

101voto

sepp2k Points 157757
@my_hash = Hash.new(Array.new)

Cela crée exactement un objet tableau, qui est renvoyé chaque fois qu'une clé n'est pas trouvée. Puisque vous ne mutez que ce tableau et que vous n'en créez jamais un nouveau, toutes vos clés renvoient au même tableau.

Ce que vous voulez faire, c'est.. :

@my_hash = Hash.new {|h,k| h[k] = Array.new }

ou simplement

@my_hash = Hash.new {|h,k| h[k] = [] }

Transmettre un bloc à Hash.new diffère de la simple transmission d'un argument de deux façons :

  1. Le bloc est exécuté chaque fois qu'une clé n'est pas trouvée. Vous obtiendrez donc un nouveau tableau à chaque fois. Dans la version avec un argument, cet argument est évalué une fois (avant que new est appelé) et le résultat est renvoyé à chaque fois.

  2. En faisant h[k] = vous insérez effectivement la clé dans le hachage. Si vous ne le faites pas, vous accédez simplement à @my_hash[some_key] ne causera pas réellement de some_key à insérer dans le hachage.

7voto

Incidently Points 1321

Essayez ceci :

@my_hash = Hash.new { |h, k| h[k] = Array.new }

2voto

yock Points 3729

L'argument de Hash.new est la valeur par défaut pour les nouvelles clés de hachage, donc lorsque vous lui passez une référence, cette référence sera utilisée pour les nouvelles clés de hachage. Vous mettez à jour cette référence lorsque vous appelez...

hash["key"].push "value"

Vous devez passer une nouvelle référence dans la clé de hachage avant d'y insérer des valeurs...

hash["key1"] = Array.new
hash["key1"].push "value1"
hash["key2"] = Array.new
hash["key2"].push "value2

Vous pouvez également essayer de l'encapsuler dans une méthode d'aide.

Prograide.com

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.

Powered by:

X