Possível acessar o índice em um Hash a cada loop?

119

Provavelmente estou perdendo algo óbvio, mas existe uma maneira de acessar o índice / contagem da iteração dentro de um hash em cada loop?

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)?
}
Atualização
fonte
3
Anon: Não, os hashes não são classificados.
Mikael S
os hashes não são tecnicamente classificados, mas em ruby ​​você pode classificá-los de certo modo. sort () irá convertê-los para um ordenado matriz aninhada, que você pode então converter de volta para um hash: your_hash.sort.to_h
jlesse

Respostas:

296

Se você gostaria de conhecer o Índice de cada iteração, poderia usar .each_with_index

hash.each_with_index { |(key,value),index| ... }
VOCÊS
fonte
24
especificamente:hash.each_with_index { |(key,value),index| ... }
rampion
22
os parênteses são necessários b / c hash.eachfornece cada par de valor-chave em um Array. Os parênteses fazem a mesma coisa que (key,value) = arr, colocando o primeiro valor (a chave) em keye o segundo em value.
Rampion
1
Obrigado @ S.Mark, @rampion, que funcionou. Eu não vi each_with_indexlistado no RDoc para Hash: ruby-doc.org/core/classes/Hash.html . Agora vejo que é um membro do Enumerable. Pena que o RDoc não possa cruzar a referência each_with_indexdo Hash.html.
Atualizandodave
2
@Dave_Paroulek Eu sempre desejei o mesmo. Eu descobri que a verificação manual dos módulos pai é uma etapa necessária ao usar o vi para verificar os métodos de uma classe. Frequentemente, apenas pulo irbe uso ClassName#instance_methodspara garantir que não perca nada.
Rampion
Thx, @rampion, ClassName#instance_methodstem sido muito útil
Atualizandodave
11

Você pode iterar sobre as chaves e obter os valores manualmente:

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: por comentário de rampion, também aprendi que você pode obter a chave e o valor como uma tupla se você iterar sobre 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
fonte
Voto negativo para acessar a coleção iterada de dentro do loop e um código incorreto: keyno primeiro loop há uma matriz de pares de chave + valor, portanto, usá-lo como um índice hashestá errado. Você já testou?
SasQ