Decrementing for loop in coffeescript

2019-01-23 22:59发布

I know how to do a incrementing for loop in coffeescript such as:

Coffeescript:

for some in something

Generated Javascript:

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

How do I create a decrementing for loop similar to this in Coffeescript?

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

6条回答
啃猪蹄的小仙女
2楼-- · 2019-01-23 23:37

There doesn't seem to be an elegant way to loop in reverse.

I checked the GitHub ticket regarding this, but it has been closed: https://github.com/jashkenas/coffee-script/issues/1187

The syntax used to be:

for some in something by -1

But it has been removed in recent versions. EDIT: it works now (for 1.6.2 @time of edit)

查看更多
淡お忘
3楼-- · 2019-01-23 23:47

Idiomatic way (from docs) along the lines of:

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

(Edited after @Trevor's note)

Edit:

Although, if performance is critical, this equivalent but maybe less aesthetic snippet will generate less resulting javascript:

lst = [1,2,3]
i = lst.length
alert lst[i] while i--
查看更多
Evening l夕情丶
4楼-- · 2019-01-23 23:54

A different take just for the record:

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

(will break on falsy values)

查看更多
仙女界的扛把子
5楼-- · 2019-01-23 23:57

EDIT: As of CoffeeScript 1.5 by -1 syntax is supported.

First, you should familiarize yourself with the by keyword, which lets you specify a step. Second, you have to understand that the CoffeeScript compiler takes a very naïve approach to loop endpoints (see issue 1187, which Blender linked to), which means that

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

will result in an infinite loop—it starts at index 0, increments the index by -1, and then waits until the index hits something.length. Sigh.

So you need to use the range loop syntax instead, which lets you specify those endpoints yourself—but also means you have to grab the loop items yourself:

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

Obviously that's pretty messy. So you should strongly consider iterating over something.reverse() instead. Just remember that reverse() modifies the array that you call it on! If you want to preserve an array but iterate over it backwards, you should copy it:

for some in something.slice(0).reverse()
查看更多
小情绪 Triste *
6楼-- · 2019-01-23 23:57

For a decrementing, index-based for loops, you can use:

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

This removes the messiness @TrevorBurnham mentioned is an issue with specifying endpoints yourself.

When something.length is 0, this is equivalent to

for i in []
查看更多
爷的心禁止访问
7楼-- · 2019-01-24 00:02

As of coffee-script 1.5.0 this is supported:

for item in list by -1
  console.log item

This will translate into

var item, _i;
for (_i = list.length - 1; _i >= 0; _i += -1) {
  item = list[_i];
  console.log(item);
}
查看更多
登录 后发表回答