2011-10-27 10 views
25

sé cómo hacer un incremento de bucle en CoffeeScript tales como:decremento de bucle en CoffeeScript

CoffeeScript:

for some in something 

generada Javascript:

for (_i = 0, _len = something.length; _i < _len; _i++) 

¿Cómo se crea una decrementando para un bucle similar a este en Coffeescript?

for (var i = something.length-1; i >= 0; i--) 

Respuesta

50

EDIT: A partir de CoffeeScript es compatible 1,5 by -1 sintaxis.

En primer lugar, debe familiarizarse con la palabra clave by, que le permite especificar un paso. En segundo lugar, usted tiene que entender que el compilador CoffeeScript tiene un enfoque muy ingenuos a los puntos finales de bucle (ver issue 1187, que Blender vinculada a), lo que significa que

for some in something by -1 # don't do this!!! 

dará lugar a un bucle infinito-que comienza en el índice 0 , incrementa el índice en -1 y luego espera hasta que el índice llegue al something.length. Suspiro.

Así que hay que utilizar la sintaxis de bucle rango en lugar, que le permite especificar los criterios de valoración a sí mismo, pero también significa que tiene que agarrar los objetos de bucle a sí mismo:

for i in [something.length - 1..0] by -1 
    some = something[i] 

Obviamente eso es bastante desordenado. Por lo tanto, debe considerar iterar más de something.reverse() en su lugar. ¡Solo recuerda que reverse() modifica la matriz en la que lo llamas!Si desea conservar una matriz, pero iterar sobre ella hacia atrás, debe copiarlo:

for some in something.slice(0).reverse() 
+1

Creo que ni siquiera necesita el '-1'. 'para mí en [sth.length-1..0]' funciona bien –

+4

@RicardoTomasi Está en lo cierto de que funcionará sin el 'por -1', pero es menos eficiente: observe la salida compilada para ambos. Desde la perspectiva del compilador, 'something.length' es potencialmente negativo, por lo que el paso es potencialmente' 1' o '-1'. –

+0

+1 para '.slice (0) .reverse()', ¡justo lo que estaba buscando! –

0

manera idiomático (de docs) a lo largo de las líneas de:

lst = ['a', 'b', 'c'] 
for n in (num for num in [lst.length-1..0]) 
    alert lst[n] 

(Editado después de @ nota de Trevor)

Editar:

Aunque, si el rendimiento es fundamental, este fragmento equivalente pero quizás menos estético generará l ess resultante javascript:

lst = [1,2,3] 
i = lst.length 
alert lst[i] while i-- 
+0

Umm, esto sólo funciona si '' lst' es [1,2,3] '. Si intenta, digamos, 'lst = ['a', 'b', 'c']', la salida seguirá siendo '3',' 2', '1'. –

+0

Derecha, código fijo. La segunda versión es correcta sin embargo. –

1

No parece haber una manera elegante de realizar un ciclo inverso.

he comprobado el billete GitHub con respecto a este, pero se ha cerrado: https://github.com/jashkenas/coffee-script/issues/1187

La sintaxis utilizada para ser:

for some in something by -1 

Pero se ha eliminado en las versiones recientes. EDIT: ahora funciona (por 1.6.2 @time de edición)

2

Una opinión diferente sólo para el registro:

i = something.length 
while item = something[--i] 
    #use item 

(se romperá en los valores Falsy)

+0

éste no se rompe cuando se usa sobre matrices vacías – david

37
Como

de coffeescript 1.5.0 ello apoyado:

for item in list by -1 
    console.log item 

esto tra nslate en

var item, _i; 
for (_i = list.length - 1; _i >= 0; _i += -1) { 
    item = list[_i]; 
    console.log(item); 
} 
+2

También puede usar la sintaxis 'element, index' con esto como: ' console.log "# {item.toString()} en el índice # {index}" for artículo, índice en lista por -1 – glampr

0

Para un decremento, índice de base de bucles, puede utilizar:

for i in [0...something.length].reverse() 

Esto elimina el desorden @TrevorBurnham mencionado es un problema con especificando los puntos finales a sí mismo.

Cuando something.length es 0, esto es equivalente a

for i in [] 
Cuestiones relacionadas