短絡的に Array.forEach を呼び出すようにブレーク

[1,2,3].forEach(function(el) {
    if(el === 1) break;
});

JavaScriptの新しいforEachメソッドを使ってどのようにすればよいのでしょうか?私は return;, return false;, break を試しました。break "はクラッシュし、"return "は反復を続けるだけで何もしません。

ソリューション

forEachには、break`する機能は組み込まれていません。実行を中断するには、ある種の例外を投げなければなりません。

var BreakException = {};

try {
  [1, 2, 3].forEach(function(el) {
    console.log(el);
    if (el === 2) throw BreakException;
  });
} catch (e) {
  if (e !== BreakException) throw e;
}

JavaScript の例外はあまりきれいではありません。その中で本当に break する必要があるなら、伝統的な for ループの方が適切かもしれません。

Array#some`を使う

代わりに、Array#some`を使用します。

[1, 2, 3].some(function(el) {
  console.log(el);
  return el === 2;
});

これは、配列順に実行されたコールバックのいずれかが true を返すと同時に sometrue を返し、残りのコールバックの実行を短絡させることで動作します。

some、その逆の [every][2] (これはreturn falseで停止します)、およびforEachはすべて ECMAScript Fifth Edition のメソッドであり、これらが欠けているブラウザではArray.prototype` に追加する必要があります。

解説 (14)

jqueryeach`メソッドは、コールバック関数内でfalseを返すことができるので、その使用を検討してください。

$.each(function(e, i) { 
   if (i % 2) return false;
   console.log(e)
})

LodashのライブラリにはtakeWhile`というメソッドがあり、map/reduce/foldなどとチェインすることができます。

var users = [
  { 'user': 'barney',  'active': false },
  { 'user': 'fred',    'active': false },
  { 'user': 'pebbles', 'active': true }
];

_.takeWhile(users, function(o) { return !o.active; });
// => objects for ['barney', 'fred']

// The `_.matches` iteratee shorthand.
_.takeWhile(users, { 'user': 'barney', 'active': false });
// => objects for ['barney']

// The `_.matchesProperty` iteratee shorthand.
_.takeWhile(users, ['active', false]);
// => objects for ['barney', 'fred']

// The `_.property` iteratee shorthand.
_.takeWhile(users, 'active');
// => []
解説 (3)

他のサイトでこの解決策を見つけました。try / catchシナリオでforEachを包むことができます。

if(typeof StopIteration == "undefined") {
 StopIteration = new Error("StopIteration");
}

try {
  [1,2,3].forEach(function(el){
    alert(el);
    if(el === 1) throw StopIteration;
  });
} catch(error) { if(error != StopIteration) throw error; }

詳細はこちら: http://dean.edwards.name/weblog/2006/07/enum/

解説 (1)