¿Es posible acceder al índice en un Hash en cada bucle?

119

Probablemente me esté perdiendo algo obvio, pero ¿hay alguna manera de acceder al índice / recuento de la iteración dentro de un hash en cada bucle?

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)?
}
Upgradingdave
fuente
3
Anon: No, los hash no se ordenan.
Mikael S
los hashes no están ordenados técnicamente, pero en ruby ​​puedes ordenarlos en cierto sentido. sort () los convertirá en una matriz anidada ordenada, que luego puede volver a convertir en un hash: your_hash.sort.to_h
jlesse

Respuestas:

296

Si desea conocer el índice de cada iteración, puede usar .each_with_index

hash.each_with_index { |(key,value),index| ... }

fuente
24
específicamente:hash.each_with_index { |(key,value),index| ... }
rampion
22
los parens son necesarios b / c hash.eachproporciona cada par clave-valor en un Array. Los parens hacen lo mismo que (key,value) = arrponer el primer valor (la clave) en keyy el segundo en value.
rampion
1
Gracias @ S.Mark, @rampion, eso funcionó. No vi each_with_indexen el RDoc para Hash: ruby-doc.org/core/classes/Hash.html . Ahora veo que es miembro de Enumerable. Pero es una lástima que RDoc no pueda hacer referencias cruzadas each_with_indexde Hash.html.
Actualización el
2
@Dave_Paroulek A menudo he deseado lo mismo. Descubrí que verificar los módulos principales manualmente es un paso necesario cuando utilizo vi para verificar los métodos de una clase. A menudo, simplemente salto irby uso ClassName#instance_methodspara asegurarme de que no haya nada que me haya perdido.
rampion
Thx, @rampion, ClassName#instance_methodsha sido muy útil
Upgradingdave
11

Puede iterar sobre las claves y obtener los 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

EDITAR: según el comentario de rampion, también aprendí que puede obtener tanto la clave como el valor como una tupla si repite 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
fuente
Votado hacia abajo por acceder a la colección iterada desde el interior del bucle y un código erróneo: keyen el primer bucle hay una matriz de par clave + valor, por lo que usarlo como índice hashes incorrecto. ¿Lo has probado alguna vez?
SasQ