2010-05-28 10 views
14

Estoy tratando de resolver un problema de Project Euler usando Ruby, utilicé 4 métodos diferentes de bucle, el método for-loop, tiempos, rango y upto, sin embargo el método times solo produce la respuesta esperada, mientras que el método for-loop, range y upto no. Supongo que son algo así, pero descubrí que no es así. ¿Alguien puede explicar las diferencias entre estos métodos?Diferencias de bucle en Ruby usando Rango vs. Tiempos

Aquí está la estructura de bucle Solía ​​

# for-loop method 
for n in 0..1 
    puts n 
end 

0 
1 
=> 0..1 

# times method 
2.times do |n| 
    puts n 
end 

0 
1 
=> 2 

# range method 
(0..1).each do |n| 
    puts n 
end 

0 
1 
=> 0..1 

# upto method 
0.upto(1) do |n| 
    puts n 
end 

0 
1 
=> 0 

Respuesta

6

Esta información puede obtenerse fácilmente mediante la inspección de la documentación.

Array#each tiene una firma de array.each {|item| block } → array, para que podamos ver que el valor de retorno de foo.each { ... } es foo.

Del mismo modo, Int#upto tiene una firma de int.upto(limit) {|i| block } => int, por lo que x.upto(y) { ... } siempre devolverá x.

Luego también podemos ver que 2.times { ... } devolverá 2 debido a la firma de Integer#times.

estoy teniendo problemas para encontrar la documentación correcta, pero for x in y... se traduce a y.each do |x| ..., así que por eso su bucle for-in devuelve el mismo que el bucle .each.

De todos modos, dependiendo de return los valores de estos constructos de bucle son ... un enfoque extraño. No creo que esto pase mucho (¿en absoluto?) En el código idiomático de Ruby.

+0

No me parece que pregunte por el valor de retorno. – sepp2k

+0

@ sepp2k: vi que la * salida * de cada instrucción era '0 1', mientras que los valores de retorno indicados por' => 'tenían 3 valores diferentes. La pregunta podría haber sido redactada con más claridad, en cualquier caso. –

+0

Hm, probablemente tienes razón. – sepp2k

3

Si te entendí correctamente, estás preguntando por qué n.times es el único método que itera hasta, pero no incluye n. En ese caso:

Para rangos es simple: x..y define un rango de xa y inclusive y x...y define un rango de xa y exclusivo. Entonces, si quiere el mismo comportamiento que las veces, use 0...n.

Para x.upto(y) solo hay una versión que iterará hasta e incluyendo y. Esto es simplemente cómo se define y documenta hasta que funcione.

También está bastante claro por qué n.times no incluye n: si itera de 0 a n (inclusive), daría n+1 veces. Pero dado que el método se llama n.times, claramente solo debe rendir n veces.

Cuestiones relacionadas