2011-10-27 24 views
25

tôi biết làm thế nào để làm một incrementing vòng lặp for trong coffeescript như:decrementing vòng lặp for trong coffeescript

Coffeescript:

for some in something 

tạo javascript:

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

Làm thế nào để tạo ra một decrementing cho vòng lặp tương tự như thế này trong Coffeescript?

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

Trả lời

50

CHỈNH SỬA: Vì cú pháp CoffeeScript 1.5 by -1 được hỗ trợ.

Trước tiên, bạn nên tự làm quen với từ khóa by, cho phép bạn chỉ định một bước. Thứ hai, bạn phải hiểu rằng trình biên dịch CoffeeScript mất một cách tiếp cận rất ngây thơ đến điểm cuối vòng lặp (xem issue 1187, mà Blender liên kết đến), có nghĩa là

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

sẽ dẫn đến vô hạn loop-nó bắt đầu từ chỉ số 0 , tăng chỉ số lên -1 và sau đó đợi cho đến khi chỉ mục chạm vào something.length. Thở dài.

Vì vậy, bạn cần phải sử dụng cú pháp dải vòng lặp thay vào đó, cho phép bạn chỉ định những thiết bị đầu cuối cho mình-nhưng cũng có nghĩa là bạn phải lấy các mặt hàng vòng lặp tự hỏi:

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

Rõ ràng đó là khá lộn xộn. Vì vậy, bạn nên xem xét kỹ lưỡng việc lặp lại qua số something.reverse() thay thế. Chỉ cần nhớ rằng reverse() sửa đổi mảng mà bạn gọi nó trên!Nếu bạn muốn giữ một mảng nhưng lặp trên nó về phía sau, bạn nên sao chép nó:

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

Tôi nghĩ bạn thậm chí không cần '-1'. 'for i in [sth.length-1..0]' hoạt động tốt –

+4

@RicardoTomasi Bạn đúng rằng nó sẽ hoạt động mà không có 'by -1', nhưng nó kém hiệu quả hơn - hãy xem kết quả được biên dịch cho cả hai. Từ quan điểm của trình biên dịch, 'something.length' có khả năng âm, vì vậy bước này có khả năng là' 1' hoặc '-1'. –

+0

+1 cho '.slice (0) .reverse()', chỉ là những gì tôi đang tìm kiếm! –

0

cách Idiomatic (từ docs) dọc theo dòng:

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

(Chỉnh sửa sau @ lưu ý Trevor)

Edit:

Mặc dù, nếu hiệu suất là rất quan trọng, đoạn mã tương đương nhưng có lẽ ít thẩm mỹ hơn này sẽ tạo ra l ess kết quả javascript:

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

Umm, điều này chỉ hoạt động nếu 'lst' là' [1,2,3] '. Nếu bạn cố gắng, nói, 'lst = ['a', 'b', 'c']', đầu ra sẽ vẫn là '3',' 2', '1'. –

+0

Mã đúng, cố định. Phiên bản thứ 2 là chính xác mặc dù. –

1

Có vẻ như đây không phải là cách thanh lịch để đảo ngược.

Tôi đã kiểm tra vé GitHub về vấn đề này, nhưng nó đã bị đóng cửa: https://github.com/jashkenas/coffee-script/issues/1187

Cú pháp được sử dụng là:

for some in something by -1 

Nhưng nó đã bị loại bỏ trong các phiên bản gần đây. CHỈNH SỬA: nó hoạt động ngay bây giờ (đối với 1.6.2 @ thời gian chỉnh sửa)

2

Một mất khác nhau chỉ dành riêng cho các kỷ lục:

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

(sẽ phá vỡ các giá trị falsy)

+0

cái này không bị vỡ khi được sử dụng trên các mảng trống – david

37

Tính đến cà phê-script 1.5.0 này được hỗ trợ:

for item in list by -1 
    console.log item 

này sẽ cá tra nslate vào

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

Bạn cũng có thể sử dụng cú pháp 'phần tử, chỉ mục' với điều này như sau: ' console.log "# {item.toString()} tại index # {index}" cho mục, chỉ mục trong danh sách theo -1' – glampr

0

Đối với một decrementing, chỉ số dựa trên vòng lặp for, bạn có thể sử dụng:

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

này loại bỏ các @TrevorBurnham hỗn độn đề cập là một vấn đề với cách xác định điểm cuối chính mình.

Khi something.length0, điều này tương đương với

for i in []