2011-10-27 26 views
25

遞減for循環,我知道該怎麼做for循環遞增在CoffeeScript中,如:在CoffeeScript中

的CoffeeScript:

for some in something 

生成的JavaScript:

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

如何創建一個在Coffeescript中遞減循環類似於這個?

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

回答

50

編輯:從CoffeeScript 1.5開始by -1支持語法。

首先,您應該熟悉by關鍵字,它允許您指定一個步驟。其次,你要明白的是,CoffeeScript的編譯器採用循環端點非常幼稚的做法(見issue 1187,其中攪拌機鏈接),這意味着

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

將導致一個無限循環,它開始於指數0 ,索引增加-1,然後等待索引達到something.length。嘆。

所以你需要使用的範圍內循環語法代替,它可以讓你指定這些端點自己,但也意味着你必須自己搶圈項目:

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

顯然,這相當混亂。所以你應該強烈考慮反覆使用something.reverse()。請記住,reverse()會修改您調用的數組!如果你想保留一個數組,但遍歷它倒退,你應該把它複製:

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

我覺得你甚至不需要'-1'。 '因爲我在[sth.length-1..0]'可以正常工作 –

+4

@RicardoTomasi你說得對,沒有'by -1'就可以工作,但效率不高 - 請看兩者的編譯輸出。從編譯器的角度來看,'something.length'可能是負數,所以這個步驟可能是'1'或'-1'。 –

+0

對於'.slice(0).reverse()'+1,正是我所期待的! –

0

成語(從docs)線沿線的方式:

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

編輯(後@特雷弗注編輯):

雖然,如果性能是至關重要的,這相當於但可能不太美觀的片段會產生l由此產生的javascript:

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

嗯,這僅適用如果'lst'是'[1,2,3]'。如果你試着說,'lst = ['a','b','c']',輸出仍然是'3','2','1'。 –

+0

正確,固定的代碼。第二版是正確的。 –

2

不同的看法僅僅是爲了記錄:

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

(將打破falsy值)

+0

在空數組上使用時不會中斷 – david

37

咖啡腳本1.5.0這種支持:

for item in list by -1 
    console.log item 

這將TRA nslate到

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

您還可以使用'element,index'語法,如下所示: 'console.log「#{item.toString()} at index#{index}」for項目,列表中的索引由-1' – glampr

0

對於遞減,指數爲基礎的循環,你可以使用:

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

這消除提到的混亂@TrevorBurnham是與自己指定端點的問題。

something.length0,這相當於

for i in []