Possible d'accéder à l'index dans un hachage à chaque boucle?

119

Il me manque probablement quelque chose d'évident, mais existe-t-il un moyen d'accéder à l'index / au nombre de l'itération dans un hachage de chaque boucle?

hash = {'three' => 'one', 'four' => 'two', 'one' => 'three'}
hash.each { |key, value| 
    # any way to know which iteration this is
    #   (without having to create a count variable)?
}
Mise à niveaudave
la source
3
Anon: Non, les hachages ne sont pas triés.
Mikael S
les hachages ne sont pas triés techniquement, mais en ruby, vous pouvez les trier dans un sens. sort () les convertira en un tableau imbriqué trié, que vous pourrez ensuite reconvertir en hachage: your_hash.sort.to_h
jlesse

Réponses:

296

Si vous souhaitez connaître l'index de chaque itération, vous pouvez utiliser .each_with_index

hash.each_with_index { |(key,value),index| ... }
TU
la source
24
spécifiquement:hash.each_with_index { |(key,value),index| ... }
rampion
22
les parenthèses sont nécessaires b / c hash.eachdonne chaque paire clé-valeur dans un Array. Les parenthèses font la même chose que (key,value) = arr, en mettant la première valeur (la clé) dans keyet la seconde dans value.
rampion
1
Merci @ S.Mark, @rampion, qui a fonctionné. Je n'ai pas vu la each_with_indexliste dans le RDoc pour Hash: ruby-doc.org/core/classes/Hash.html . Maintenant, je vois que c'est un membre d'Enumerable. Mais dommage que RDoc ne puisse pas croiser les références each_with_indexde Hash.html.
Upgradingdave
2
@Dave_Paroulek J'ai souvent souhaité la même chose. J'ai trouvé que la vérification manuelle des modules parents était une étape nécessaire lors de l'utilisation de vi pour vérifier les méthodes d'une classe. Souvent, je passe simplement à irb, et je m'en sers ClassName#instance_methodspour m'assurer que je n'ai rien manqué.
rampion
Merci, @rampion, ClassName#instance_methodsa été très utile
Upgradingdave
11

Vous pouvez parcourir les clés et extraire les valeurs manuellement:

hash.keys.each_with_index do |key, index|
   value = hash[key]
   print "key: #{key}, value: #{value}, index: #{index}\n"
   # use key, value and index as desired
end

EDIT: par commentaire de rampion, je viens également d'apprendre que vous pouvez obtenir à la fois la clé et la valeur sous forme de tuple si vous itérez sur hash:

hash.each_with_index do |(key, value), index|
   print "key: #{key}, value: #{value}, index: #{index}\n"
   # use key, value and index as desired
end
Kaleb Brasee
la source
Évalué pour accéder à la collection itérée depuis l'intérieur de la boucle et un code erroné: keydans la première boucle se trouve un tableau de paire clé + valeur, donc l'utiliser comme un index hashest faux. L'avez-vous déjà testé?
SasQ