2010-04-11 9 views
90

En Scala, a menudo se utiliza un iterador que hacer un bucle for en un orden creciente como:Scala hacia abajo o decreciente para el ciclo?

for(i <- 1 to 10){ code } 

¿Cómo hacerlo así que va de 10 a 1? Supongo que 10 to 1 da un iterador vacío (como las matemáticas de rango habitual)?

Hice una secuencia de comandos de Scala que lo resuelve llamando a la inversa en el iterador, pero no es bueno en mi opinión, es el siguiente el camino a seguir?

def nBeers(n:Int) = n match { 

    case 0 => ("No more bottles of beer on the wall, no more bottles of beer." + 
       "\nGo to the store and buy some more, " + 
       "99 bottles of beer on the wall.\n") 

    case _ => (n + " bottles of beer on the wall, " + n + 
       " bottles of beer.\n" + 
       "Take one down and pass it around, " + 
       (if((n-1)==0) 
        "no more" 
       else 
        (n-1)) + 
        " bottles of beer on the wall.\n") 
} 

for(b <- (0 to 99).reverse) 
    println(nBeers(b)) 

Respuesta

180
scala> 10 to 1 by -1 
res1: scala.collection.immutable.Range = Range(10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 
+1

@Felix: De nada. También debería haber señalado que también hay 'hasta 'que puede usar en lugar de' a' para excluir el punto final de la derecha del rango. El punto final izquierdo siempre está incluido. –

+0

Ya sabía acerca de hasta, hasta que también es una función en enteros, sin embargo, "por" debe ser una función en el rango/iterador cualquiera que sea el resultado de las funciones "hasta" y "hasta". Gracias de todos modos :) – Felix

+3

La respuesta de Randall es la mejor, pero creo que 'Range.inclusive (10, 1, -1)' merece mención. –

32

La respuesta de @Randall es bueno como el oro, pero por el bien de finalización que quería añadir un par de variaciones:

scala> for (i <- (1 to 10).reverse) {code} //Will count in reverse. 

scala> for (i <- 10 to(1,-1)) {code} //Same as with "by", just uglier. 
+9

+1 para el primero uno, pero el segundo es malo, menos legible que 'by' y IMO no debe usarse bajo ninguna circunstancia –

+4

El segundo es malo pero construye intuición sobre lo que está disponible – Zaheer

6

Después de haber programado en Pascal, encuentro esta definición agradable de usar:

implicit class RichInt(val value: Int) extends AnyVal { 
    def downto (n: Int) = value to n by -1 
    def downtil (n: Int) = value until n by -1 
} 

utiliza de esta manera:

for (i <- 10 downto 0) println(i) 
+0

Gracias por la respuesta. Tengo problemas para usar esta solución. Aquí está mi stacktrace: 'Error: (57, 17) la clase de valor no puede ser miembro de otra clase clase implícita RichInt (val value: Int) extends AnyVal { ^' – robert

+0

Como el mensaje de error (no es un seguimiento de la pila) sugiere, no se puede definir la clase de valor dentro de otra clase. O defínalo fuera de él, como en un objeto, o elimina la parte 'extends AnyVal' (que solo sirve para eliminar algunos gastos generales). –

3

Scala proporciona muchas formas de trabajar hacia abajo en el ciclo.

primera solución: con "a" y "por"

//It will print 10 to 0. Here by -1 means it will decremented by -1.  
for(i <- 10 to 0 by -1){ 
    println(i) 
} 

segundo Solución: Con "a" e "inverso"

for(i <- (0 to 10).reverse){ 
    println(i) 
} 

tercera solución: con "a" solamente

//Here (0,-1) means the loop will execute till value 0 and decremented by -1. 
for(i <- 10 to (0,-1)){ 
    println(i) 
} 
+2

Todas estas opciones ya se han cubierto (hace años). – jwvh

Cuestiones relacionadas