8
votes

Impossible d'utiliser un tableau comme valeurs par défaut pour Ruby Hash?

J'ajoutais des articles à une clé de hachage. Je m'attendais à obtenir une structure comme celle-ci: xxx pré>

J'ai utilisé un tableau pour initialiser le hachage. P> xxx pré>

puis a commencé à l'utiliser: p> xxx pré>

mais il s'avère: P>

irb> hash
 => {}


1 commentaires

Êtes-vous pas sûr de la sortie que vous voyez? Ou ce que le hachage contient réellement? On ne sait pas ce que vous recherchez ici.


4 Réponses :


2
votes

hachage ['a'] << 1 et hachage ['B'] << 2 n'est pas une syntaxe correcte pour la création d'une touche clé / valeur. Vous devez utiliser = pour cela: xxx

qui devrait vous donner le hachage {'A': [1], 'B': [2 ]}


0 commentaires

11
votes

Essayez le suivant à la place:

hash = Hash.new{|h, k| h[k] = []}
hash['a'] << 1 # => [1]
hash['b'] << 2 # => [2]


6 commentaires

+1 "Vous avez spécifié un tableau vide comme valeur par défaut, mais le même tableau est utilisé". Bingo!


Quoi?! C'est vraiment étrange pour moi. Lorsque vous utilisez une chaîne, une chaîne n'est pas réutilisée. La chaîne peut être une sorte de type de valeur, mais je pensais que "tout" était un objet dans Ruby. Pourquoi la différence entre chaînes et autres objets?


@ Cort3Z: ​​Je ne sais pas ce que tu veux dire. Peut-être que cela peut aider à montrer qu'il n'y a pas de différence: a = b = 'foo'; A.Replace 'bar'; b # => 'bar'


Peut-être que je n'étais pas clair: ce que je voulais dire était que je pense qu'il est étrange que lorsque vous faites hash.new ([]) il utilise le même objet de tableau, mais lorsque vous faites hachage ("string") Il n'utilise pas la même chaîne.


@ Cort3Z: ​​Il utilisera la même chaîne. h = hash.new ("ne fais pas ça"); h [0] .uppase!; h [1] # => "Ne faites pas cela"


@ Marc-andrélafortune maintenant je vois ce qui se passe. Je faisais h = hash.new ("w"); h ["test"] = "données"; p h ["a"] # => "w" . Je suppose que cela réaffecte l'objet pour h ["test"] uniquement et ne modifie pas réellement l'objet.



4
votes

the constructeur Vous avez utilisé des stocks [] comme le Valeur par défaut Pour revenir lors de l'accès des touches inconnues. Depuis tableau # <<< / code> modifie son récepteur en place Ce tableau initialement vide pousse.

expliquer plus en détail:

quand vous faites < Code> hachage ['A'] << 1 C'est ce qui se passe:

  1. hachage est de voir s'il y a une touche nommée 'a'
  2. Il trouve que non, il n'y a pas de telle clé.
  3. Il semble qu'il a stocké une valeur par défaut à revenir.
  4. Puisque vous l'avez construite avec hachage.new ([]) il a une telle valeur, [] et cela revient.
  5. maintenant [] << 1 est évalué et cela signifie que HASH stocke désormais [1] comme valeur à revenir lorsqu'une touche précédemment non engagée est demandée.

    Si ce que vous voulez, c'est de stocker la paire de valeurs de clé, utilisez la troisième forme du constructeur avec un bloc: xxx


0 commentaires

1
votes

Ceci est exactement le comportement que vous vous attendez à voir.

Vous n'ajoutez jamais quoi que ce soit au hachage , donc le hachage est complètement vide. Lorsque vous recherchez une clé, cette touche n'existera jamais, il renvoie donc la valeur par défaut, que vous avez spécifiée pour être un tableau . .

Alors, vous recherchez la touche 'A' , qui n'existe pas et renvoie donc le tableau que vous avez spécifié comme valeur par défaut. Ensuite, vous appelez <<< / code> sur ce tableau , qui ajoute une valeur ( 1 ).

Ensuite, vous recherchez la clé 'B' , qui n'existe pas non plus et renvoie donc le tableau que vous avez spécifié comme valeur par défaut, qui contient maintenant L'élément 1 vous a ajouté plus tôt. Ensuite, vous appelez <<< / code> sur ce tableau , ajoute la valeur 2 à celui-ci.

Vous vous retrouvez avec un hachage toujours vide, car vous ne l'ayez jamais rien ajouté. La valeur par défaut du hachage est maintenant un tableau contenant les valeurs 1 et 2 .

La sortie que vous voyez est que la IRB imprime toujours le résultat de la dernière expression qui a été évaluée. La dernière expression de votre exemple est appelée <<< / code> sur le tableau . <<< / code> renvoie son récepteur, qui est ensuite la valeur de retour de l'ensemble de l'expression et donc quelle IRB imprime.


1 commentaires

C'est exactement ce que vous demandez, et pas du tout ce que vous voulez dire!