私はnodejsとmongooseで遊んでいます - 再帰的な関数とforeachでネストしている深いコメントの中で特定のコメントを見つけようとしています。 nodejs forEachを停止する方法はありますか?私はすべてのforEachの繰り返しが関数であることを理解していて、そして単に "break"をすることはできず、ただ "return"をすることができますが、これはforeachを止めません。
function recurs(comment){
comment.comments.forEach(function(elem){
recurs(elem);
//if(...) break;
});
}
forEach
から抜け出すことはできません。それを偽造するには3つの方法が考えられます。
1.醜い方法 :forEach
への2番目の引数を context として使用し、そこにブール値を格納してからif
を使用します。これはひどいね。
2.物議を醸す方法 :すべてをtry-catch
ブロックで囲み、中断したい場合は例外をスローします。これはかなり悪く見えます、そして パフォーマンスに影響を与えるかもしれません 、しかしカプセル化することができます。
3.楽しい方法 :every()
を使ってください。
['a', 'b', 'c'].every(function(element, index) {
// Do your thing, then:
if (you_want_to_break) return false
else return true
})
return true
を壊したいのであれば、代わりにsome()
を使うことができます。
Array#forEach から抜け出すことはできません。 (これを確認するために、リンクされたページでFirefoxでそれを実装するソースコードを調べることができます。)
代わりに、通常のfor
ループを使用してください。
function recurs(comment) {
for (var i = 0; i < comment.comments.length; ++i) {
var subComment = comment.comments[i];
recurs(subComment);
if (...) {
break;
}
}
}
(または、もう少し賢くなりたい場合、comment.comments[i]
が常に目的語である場合は、:)
function recurs(comment) {
for (var i = 0, subComment; subComment = comment.comments[i]; ++i) {
recurs(subComment);
if (...) {
break;
}
}
}
場合によっては Array.some
がおそらくその要件を満たすでしょう。
他の人が指摘したように、あなたはforEach
ループをキャンセルすることはできませんが、これが私の解決策です:
ary.forEach(function loop(){
if(loop.stop){ return; }
if(condition){ loop.stop = true; }
});
もちろん、これは実際にはループを壊しません、それはただ「break」に続くすべての要素でのコード実行を妨げるだけです
Array.prototype. findを使用したいと思います Findは配列内の特定の値を見つけると自動的に壊れます。
var inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === 'cherries';
}
console.log(inventory.find(findCherries));
// { name: 'cherries', quantity: 5 }
forEachは復帰しても壊れません、この作品を手に入れるための醜い解決策がありますが、私はそれを使わないことをお勧めします。代わりにArray.prototype.some
またはArray.prototype.every
を使うようにしてください
var ar = [1,2,3,4,5];
ar.some(function(item,index){
if(item == 3){
return true;
}
console.log("item is :"+item+" index is : "+index);
});
サードパーティのライブラリを使用しても構わない場合は、Lodashの forEach
関数を使用できます。
例:
var _ = require('lodash');
_.forEach(comments, function (comment) {
do_something_with(comment);
if (...) {
return false; // Exits the loop.
}
})
Array.forEach
は壊れてはいけません、そしてtry...catch
やArray.every
やArray.some
のようなハックなメソッドを使うことはあなたのコードを理解することを難しくするだけです。この問題の解決策は2つしかありません。
1)古いfor
ループを使用します。これは最も互換性のある解決策になりますが、大きなコードブロックで頻繁に使用される場合は非常に読みにくくなります。
var testArray = ['a', 'b', 'c'];
for (var key = 0; key < testArray.length; key++) {
var value = testArray[key];
console.log(key); // This is the key;
console.log(value); // This is the value;
}
2)互換性が問題にならない場合は、新しいECMA6(2015仕様)を使用してください。 2016年になっても、この新しい仕様を適切にサポートしているブラウザとIDEはごくわずかです。これは反復可能なオブジェクト(例えば配列)に対しては有効ですが、反復不可能なオブジェクトに対してこれを使用したい場合は、Object.entries
メソッドを使用する必要があります。この方法は2016年6月18日現在ではほとんど利用できず、Chromeでもそれを有効にするための特別なフラグが必要です:chrome://flags/#enable-javascript-harmony
。配列の場合、これらすべてを必要とするわけではありませんが、互換性は問題のままです。
var testArray = ['a', 'b', 'c'];
for (let [key, value] of testArray.entries()) {
console.log(key); // This is the key;
console.log(value); // This is the value;
}
3)多くの人が最初の選択肢も2番目の選択肢も良い候補ではないことに同意するでしょう。オプション2が新しい標準になるまで、AngularJSやjQueryなどの最も人気のあるライブラリは、JavaScriptで利用できるものよりも優れた独自のループメソッドを提供します。これらの大きなライブラリをまだ使っておらず、軽量のオプションを探している人のためにも、 this のような解決策を使うことができます。
var f = "how to stop Javascript forEach?".split(' ');
f.forEach(function (a,b){
console.info(b+1);
if (a == 'stop') {
console.warn("\tposition: \'stop\'["+(b+1)+"] \r\n\tall length: " + (f.length));
f.length = 0; //<--!!!
}
});
以下のコードは条件が満たされるとforeachループを中断します、以下はサンプル例です
var array = [1,2,3,4,5];
var newArray = array.slice(0,array.length);
array.forEach(function(item,index){
//your breaking condition goes here example checking for value 2
if(item == 2){
array.length = array.indexOf(item);
}
})
array = newArray;