LoginSignup
21
21

More than 5 years have passed since last update.

[初心者用]CoffeeScriptのforが多機能なので整理するために纏めてみました

Last updated at Posted at 2013-06-05

本来は自分用メモのものですが、せっかくまとめたので抜粋。書式変更するの面倒なので、コードそのままベタ張り。

まずは基本

for element in [element1, element2, element3]   console.log element

変換後

var element, _i, _len, _ref;
_ref = [element1, element2, element3];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  element = _ref[_i];
  console.log(element);
}

一文にまとめる書き方もある。ただし、この場合処理は一つのみ。
 conosle.log(element) for element in [element1, element2, element3]

for elementの後で「, index」を入れると、インデックス番号も取得できる

for element, index in [element1, element2, element3] console.log "#{index} : #{element}"

変換後

var element, index, _i, _len, _ref;
_ref = [element1, element2, element3];
for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
  element = _ref[index];
  console.log("" + index + " : " + element);
}

一文にまとめる書き方もある。ただし、この場合処理は一つのみ。
 console.log("" + index + " : " + element) for element, index in [element1, element2, element3]

for文の後ろにwhenを入れると、条件を満たすものだけ処理を行うことができる

for element, index in [element1, element2, element3] when element == element1 console.log "#{index} : #{element}"[/code]

変換後

var element, index, _i, _len, _ref;
_ref = [element1, element2, element3];
for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
  element = _ref[index];
  if (element === element1) {
    console.log("" + index + " : " + element);
  }
}

受け皿となる変数を用意すると、forで回して処理を行った結果を配列として受け取ることができる。

collection = for element in [element1, element2, element3] element * 5

変換後

var collection, element;
collection = (function() {
  var _i, _len, _ref, _results;
  _ref = [element1, element2, element3];
  _results = [];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    element = _ref[_i];
    _results.push(element * 5);
  }
  return _results;
})();

一文にまとめることも可能。ただしこの場合は処理は一つのみ。また、必ず括弧で囲まないと、下記の例では「collection = element * 5」という処理になってしまうので注意。これは正直一文にまとめるものではないと考える。
collection = (element * 5 for element in [element1, element2, element3]) 

whenによる条件式も反映されるので、応用として、特定の条件を通過したエレメントのみを配列として受け取ることができる。上記同様、処理したものを戻すことも可能。

collection = for element in [element1, element2, element3] when element.prop == 0 element

変換後

var collection, element;
collection = (function() {
  var _i, _len, _ref, _results;
  _ref = [element1, element2, element3];
  _results = [];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    element = _ref[_i];
    if (element.prop === 0) {      _results.push(element);    }
  }
  return _results;
})();

一行にまとめることも可能・・・だけど、もうなんだか訳が分からなくなるような感じ。
collection = (element for element in [element1, element2, element3] when element.prop == 0) 

以上は、連番の配列(Array)。連想配列(Object)はfor - ofを使う。基本Key-Value両方欲しいものなので、以下の書き方で固定しておくとよいと思われる。

for key, value of {key1:1, key2:2, key3:3} console.log "#{key} : #{value}"
変換後
var key, value, _ref; _ref = {   key1: 1,   key2: 2,   key3: 3 }; for (key in _ref) {   value = _ref[key];  console.log("" + key + " : " + value); }

一文にまとめることも可能。ただし、この場合処理は一つのみ。

console.log "#{key} : #{value}" for key, value of {key1:1, key2:2, key3:3}

指定回数ループさせたい場合

for i in [0...10] console.log i

変換後

var i, _i;
for (i = _i = 0; _i < 10; i = ++_i) {
  console.log(i);
}

指定個数の要素を連番で入れた配列を渡せば、従来通りのfor文が作れる。逆順も可能。今までの配列走査は頭からしかできなかったので、逆順で走査したいときはこの方法か、whileを使用する。
for i in [9..0]
console.log i

変換後
var i, _i;
for (i = _i = 9; _i >= 0; i = --_i) {
  console.log(i);
}

連番要素の配列の作り方の説明は割愛。 [0...10]で0以上10未満、[0..10]で0以上10以下になるので注意。通常のfor文の作り方であれば、ドット3つの方を覚えておけばよい。

あと、必ず0から始める必要はない。[5, 6, 7]とかでもいい。

固定数を元に、飛び飛びで処理したい場合(i++ではなくi+=2的な)

for i in [0...10] by 2  console.log i

変換後

var i, _i;
for (i = _i = 0; _i < 10; i = _i += 2) {
  console.log(i);
}

指定のプロパティ(キー)を、オブジェクトが持っているかどうかを調べた上で処理を行う。

JSでは「hasOwnProperty」を使うわけで、そのための仕組みを既にfor文用に仕込んである。これは定型と考えてよい。keyの前にownを記述すると、hasOwnPropertyを使用した条件式が組み込まれる。

for own key, value of object
  value * 5

変換後

var key, value,
__hasProp = {}.hasOwnProperty;
for (key in object) {
  if (!__hasProp.call(object, key)) continue;
  value = object[key];
  value * 5;
}

一文にまとめることも可能。ただし、処理は一つのみ。

value * 5 for own key, value of object

【番外編】for文の中で関数を作って処理する

for文の中で関数を扱いたい場合、for文の外部で関数を作ってそれを使うのもいいのだけれど、for文の中でしか使わない関数の場合、その中で作ることも可能。関数を作るときはdoを使う。すると、JSに変換後、その関数を外部化してくれて、使いまわせるようになっている。(ただし関数オブジェクトの名前は_fnとか_fn1とか勝手につけられるので、その場所以外で使うことはできない)

for elm in [1...5]
  do (elm)->
   alert(elm)

変換後

var elm, _fn, _i;

_fn = function(elm) {
  return alert(elm);
};
for (elm = _i = 1; _i < 5; elm = ++_i) {
  _fn(elm);
}

for文以外のところでdoを使った関数作成を行うと、即時関数「(function(){})()」を作成する。まぁ使い道がないわけではないのだが、forとは違う使い方になるのには注意。

これもまた、一文にまとめることはできるが、括弧でくくったりして解りづらくなるので外部で作るか、1文にまとめずに数行にわたって書くことを推奨したい。いつものことながら処理は1つのみ。

(do (elm)-> alert(elm)) for elm in [1...5]
21
21
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
21