web-dev-qa-db-ja.com

Coffeescriptのforループのデクリメント

私は次のようなコーヒースクリプトでforループのインクリメントを行う方法を知っています:

Coffeescript:

for some in something

生成されたJavascript:

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

Coffeescriptでこれに似たデクリメントforループを作成するにはどうすればよいですか?

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

編集:CoffeeScript 1.5以降_by -1_構文がサポートされています。

まず、ステップを指定できるbyキーワードをよく理解しておく必要があります。次に、CoffeeScriptコンパイラがエンドポイントをループするために非常にナイーブなアプローチを取っていることを理解する必要があります(Blenderがリンクしている 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()
_
51
Trevor Burnham

コーヒースクリプトの時点で 1.5. これはサポートされています:

for item in list by -1
  console.log item

これはに変換されます

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

記録のためだけに別の見方:

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

(偽の値で壊れます)

2
Ricardo Tomasi

逆にループするエレガントな方法はないようです。

これに関してGitHubチケットを確認しましたが、クローズされました: https://github.com/jashkenas/coffee-script/issues/1187

以前の構文は次のとおりです。

for some in something by -1

ただし、最近のバージョンでは削除されています。編集:今は動作します(1.6.2 @編集時)

1
Blender

次の行に沿った慣用的な方法( docs から):

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

(@ Trevorのメモの後に編集)

編集:

ただし、パフォーマンスが重要な場合、この同等であるが美的でないスニペットは、生成されるjavascriptが少なくなります。

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

インデックスベースのforループをデクリメントするには、次を使用できます。

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

これにより、@ TrevorBurnhamがエンドポイントを自分で指定する際の問題であると述べた、混乱が解消されます。

いつ something.length0、これは同等です

for i in []
0
yndolok