2009-02-10 38 views
125

Quiero usar una para cada uno-y un contador:Contador automático en Ruby para cada uno?

i=0 
for blah in blahs 
    puts i.to_s + " " + blah 
    i+=1 
end 

¿Hay una mejor manera de hacerlo?

Nota: no sé si blahs es un array o un hash, pero que tiene que ver blahs[i] no haría mucho más atractivo. También me gustaría saber cómo escribir i++ en Ruby.


Técnicamente, es la respuesta de Squeegy Matt y llegó en primer lugar, pero yo estoy dando mejor respuesta a la paradoja tan extendido en torno a los puntos un poco en SO. También su respuesta tenía la nota sobre las versiones, que sigue siendo relevante (siempre que mi Ubuntu 8.04 esté usando Ruby 1.8.6).


Debería haber utilizado puts "#{i} #{blah}" que es mucho más breve.

+0

No hay operador de incremento en Ruby. El n + = 1 que escribió allí es el equivalente más cercano. Tendría que ser azúcar sintáctico para n + = 1, que es en sí mismo abreviatura para n = n + 1. La idea de ++ fue rechazada porque oculta el hecho de que estás reasignando la variable. http://rubyurl.com/Dsb1 – Chuck

+0

¡Agradable! Gracias Chuck. Me vi obligado a aprender ++ i y i ++ en Java, así que pensé que siempre estaría ahí. –

Respuesta

183

Como ya se ha dicho, puede utilizar

each_with_index 

pero si quieres índices con un iterador diferente a "cada uno" (por ejemplo, si desea asignar un índice o algo así) puede concatenar enumeradores con el método each_with_index, o simplemente usar with_index:

blahs.each_with_index.map { |blah, index| something(blah, index)} 

blahs.map.with_index { |blah, index| something(blah, index) } 

Esto es algo que puede hacer desde ruby ​​1.8.7 y 1.9.

+1

Vale la pena señalar que esto es nuevo en 1.9. –

+1

Bien manchado. En realidad, también está en 1.8.7, pero es algo que vale la pena agregar. – paradoja

+0

¿Por qué estoy en Ruby 1.8.6 si acabo de instalar todo en Ubuntu? ¿Es 1.8.7 experimental/beta? –

10

Sí, es collection.each hacer bucles, y luego each_with_index para obtener el índice.

Probablemente deberías leer un libro de Ruby porque es fundamental Ruby y si no lo sabes, vas a estar en un gran problema (prueba: http://poignantguide.net/ruby/).

Tomado del código fuente Ruby:

hash = Hash.new 
%w(cat dog wombat).each_with_index {|item, index| 
    hash[item] = index 
} 
hash #=> {"cat"=>0, "wombat"=>2, "dog"=>1} 
+0

Gracias por el enlace (excelente) y la respuesta. –

+0

No hay problema, me complace ayudarlo. No quise ser "malvado" con respecto al bloque de cada uno: estos son constructos fundamentales de ruby ​​y aprenderlos sobre la marcha será realmente, muy doloroso. :) ¡Es mejor morder la bala y pasar unas horas leyendo! –

+0

No se preocupe, gracias por su respuesta, @Matt. –

53
[:a, :b, :c].each_with_index do |item, i| 
    puts "index: #{i}, item: #{item}" 
end 

Usted no puede hacer esto por. Por lo general, me gusta la llamada más declarativa a cada persona de todos modos. En parte porque es fácil pasar a otras formas cuando alcanza el límite de la sintaxis for.

+0

Bien, veo el punto sobre los límites con la sintaxis for. Tengo que acostumbrarme a los bloques con múltiples parámetros. –

1

Si blahs es una clase que mezcla en Enumerable, usted debe ser capaz de hacer esto:

blahs.each_with_index do |blah, i| 
    puts("#{i} #{blah}") 
end 
4

En cuanto a su pregunta sobre hacer i++, bien, no puede hacer eso en Ruby. La declaración i += 1 que tenía es exactamente cómo se supone que debe hacerlo.

+0

Genial, gracias, eso fue cubierto en los comentarios sobre la pregunta ... –

6

Si usted no tiene la nueva versión de each_with_index, puede utilizar el método zip para emparejar los índices de elementos:

blahs = %w{one two three four five} 
puts (1..blahs.length).zip(blahs).map{|pair|'%s %s' % pair} 

que produce:

1 one 
2 two 
3 three 
4 four 
5 five 
+1

¿Dónde puedo encontrar este código de su respuesta ''% s% s'% [1," dos "]' en los documentos de Ruby? Gracias por su ayuda y por conservar el espacio vertical utilizando una línea para comprimir y mapear. –

+1

En este contexto, el operador% -sign es un método de la clase String. Puede leer sobre esto en http://ruby-doc.org/core/classes/String.html#M000770. O puede escribir ri String #% en el símbolo del sistema. O puede escribir ri% para ver todas las clases documentadas que lo reconocen, por ejemplo, el significado más familiar en ri Fixnum #%. – George

1

Si desea obtener índice de rubí para cada uno, luego puede usar

.each_with_index 

Aquí hay una n ejemplo para mostrar cómo .each_with_index obras:

range = ('a'..'z').to_a 
length = range.length - 1 
range.each_with_index do |letter, index| 
    print letter + " " 
    if index == length 
     puts "You are at last item" 
    end 
end 

Esto imprimirá:

a b c d e f g h i j k l m n o p q r s t u v w x y z You are at last item 
Cuestiones relacionadas