2011-10-27 14 views
25

so come fare un incremento per il ciclo in CoffeeScript quali:decremento per il ciclo in CoffeeScript

CoffeeScript:

for some in something 

Generated Javascript:

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

Come posso creare un decrementando per loop simile a questo in Coffeescript?

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

risposta

50

EDIT: Come di CoffeeScript 1,5 by -1 sintassi è supportata.

In primo luogo, è necessario acquisire familiarità con la parola chiave by, che consente di specificare un passaggio. In secondo luogo, si deve capire che il compilatore CoffeeScript adotta un approccio molto ingenuo endpoint di loop (vedi issue 1187, che Blender legato a), il che significa che

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

si tradurrà in un infinito loop-inizia in corrispondenza dell'indice 0 , incrementa l'indice di -1 e quindi attende finché l'indice non raggiunge something.length. Sospiro.

quindi è necessario utilizzare la sintassi di loop, invece, che consente di specificare i punti finali da soli, ma significa anche che devi afferrare gli oggetti di loop da soli:

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

Ovviamente questo è piuttosto disordinato. Quindi dovresti prendere in considerazione la possibilità di iterare su something.reverse(). Ricorda che lo reverse() modifica l'array su cui lo chiami!Se si desidera conservare una matrice, ma scorrere su di esso al contrario, si dovrebbe copiarlo:

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

Penso che non sia nemmeno necessario il '-1'. 'per i in [sth.length-1..0]' funziona bene –

+4

@RicardoTomasi Hai ragione che funzionerà senza 'by -1', ma è meno efficiente - guarda l'output compilato per entrambi. Dal punto di vista del compilatore, 'something.length' è potenzialmente negativo, quindi il passaggio è potenzialmente' 1' o '-1'. –

+0

+1 per '.slice (0) .reverse()', proprio quello che stavo cercando! –

0

modo idiomatico (da docs) lungo le linee di:

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

(A cura dopo @ nota di Trevor)

Edit:

Anche se, se le prestazioni è fondamentale, questo equivalente ma forse meno snippet estetico genererà l ess risultante javascript:

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

Umm, questo funziona solo se '' lst' è [1,2,3] '. Se provi, ad esempio, 'lst = ['a', 'b', 'c']', l'output sarà ancora '3',' 2', '1'. –

+0

Diritto, codice fisso. La seconda versione è corretta però. –

1

Non sembra essere un modo elegante per eseguire il ciclo al contrario.

ho controllato il biglietto GitHub per quanto riguarda questo, ma è stato chiuso: https://github.com/jashkenas/coffee-script/issues/1187

La sintassi utilizzata per essere:

for some in something by -1 

Ma è stata rimossa nelle versioni più recenti. EDIT: ora funziona (per 1.6.2 @time di modifica)

2

un approccio diverso solo per la cronaca:

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

(si romperà su valori falsy)

+0

questo non si interrompe quando viene utilizzato su array vuoti – david

37

Come di caffè-script 1.5.0 questo è supportato:

for item in list by -1 
    console.log item 

Ciò Trà nslate in

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

È inoltre possibile utilizzare la sintassi 'elemento, indice' con questo come: ' console.log "# {item.toString()} all'indice # {indice}" per elemento, indice nella lista di -1' – glampr

0

Per un decremento, indice a base per loop, è possibile utilizzare:

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

Ciò elimina la @TrevorBurnham disordine citato è un problema con specifica endpoint te stesso.

Quando something.length è 0, questo equivale a

for i in []