शॉर्ट सर्किट Array.forEach जैसे कॉलिंग ब्रेक


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

मैं forEachजावास्क्रिप्ट में नई विधि का उपयोग कैसे कर सकता हूं ? मैंने कोशिश की है return;, return false;और breakbreakक्रैश returnकरता है और कुछ नहीं करता है लेकिन पुनरावृति जारी रखता है।


6
यह ध्यान देने योग्य है कि जबकि returnवास्तव में पुनरावृत्ति जारी रहती है, यह ब्लॉक में इसके बाद आने वाले किसी भी कोड को छोड़ देगा। उदाहरण के लिए इस कोड को लें: [1,2,3].forEach(function(el) { if(el === 2) { console.log(`Match on 2!`); return; } console.log(el); });व्याप्ति console.log(el);को छोड़ दिया जब 2 मिलान किया जाता है हो जाएगा।
शेन

5
TL; DR: मैं आप में से बहुत से समय बचाऊंगा। मैं हाल ही में JS का बहुत उपयोग कर रहा हूं। उत्तर (28 में से ...) जो आप शायद देख रहे हैं यह एक है: stackoverflow.com/a/32101207/1599699
एंड्रयू

जवाबों:


2141

में कोई अंतर्निहित क्षमता नहीं breakहै forEach। निष्पादन को बाधित करने के लिए आपको किसी प्रकार के अपवाद को फेंकना होगा। जैसे।

var BreakException = {};

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

जावास्क्रिप्ट अपवाद बहुत सुंदर नहीं हैं। एक पारंपरिक forलूप अधिक उपयुक्त हो सकता है यदि आपको वास्तव में breakइसके अंदर की जरूरत है ।

उपयोग Array#some

इसके बजाय, उपयोग करें Array#some:

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

इसका कारण यह है काम करता है someरिटर्न trueजैसे ही कॉलबैक के किसी भी रूप में, सरणी आदेश, बदले में मार डाला true, शॉर्ट-सर्किट बाकी के निष्पादन।

some, इसका उलटा every(जो एक पर रुक जाएगा return false), और forEachसभी ECMAScript पाँचवें संस्करण के तरीके हैं जो उन Array.prototypeब्राउज़रों पर जोड़े जाने की आवश्यकता होगी जहां वे गायब हैं।


109
यह न तो अधिक पठनीय है, और न ही लूप के लिए एक सामान्य का उपयोग करने की तुलना में अधिक प्रदर्शनकारी है। जवाब "इस मामले में forEach का उपयोग न करें" -1
BT

37
मुझे लगता है कि "कुछ" यहां ठीक है, क्यों जल्दी बाहर निकलने के अनुकूलन का उपयोग न
करें-

28
दिमाग लगाने के लिए धन्यवाद someऔर every, यह उत्तर में TOP पर होना चाहिए। समझ में नहीं आता है कि लोगों को क्यों लगता है कि यह कम पठनीय है। यह सिर्फ भयानक है!
कार्ल एडलर

9
का उपयोग Array#someवास्तव में अच्छा है। सबसे पहले ie9 और फ़ायरफ़ॉक्स 1.5 सहित अधिकांश ब्राउज़रों के साथ संगत भी वास्तव में अच्छी तरह से काम करता है। मेरा उदाहरण उपयोग मामला श्रेणियों की एक सरणी में सूचकांक को खोजने के लिए होगा [ए, बी] जहां एक संख्या एक निचली सीमा और ऊपरी सीमा जोड़ी के बीच होती है, जब पाया जाता है तो परीक्षण और वापसी सही होती है। for..ofकेवल नए ब्राउज़रों के लिए हालांकि अगला सबसे अच्छा समाधान होगा।
सोजिमाक्सी 16

95
नियंत्रण संभाल के रूप में अपवाद हैंडलिंग का उपयोग नहीं किया जाना चाहिए। अवधि।
फ्रैंक

479

लूप के लिए नए का उपयोग करके ECMAScript2015 (उर्फ ES6) में ऐसा करने का एक और बेहतर तरीका है । उदाहरण के लिए, यह कोड संख्या 5 के बाद सरणी तत्वों को प्रिंट नहीं करता है:

let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let el of arr) {
  console.log(el);
  if (el === 5) {
    break;
  }
}

डॉक्स से:

दोनों के लिए ... में और के लिए ... बयानों के कुछ पर iterate। उन दोनों के बीच मुख्य अंतर यह है कि वे किस पर चलते हैं। के लिए ... में बयान एक वस्तु का गणनीय गुण, मूल प्रविष्टि के क्रम में अधिक iterates। के लिए ... कथन का डेटा डेटा पर पुनरावृत्त होता है जो पुनरावृत्त वस्तु को पुनरावृत्त होने के लिए परिभाषित करता है।

पुनरावृत्ति में सूचकांक की आवश्यकता है? आप उपयोग कर सकते हैं Array.entries():

for (const [index, el] of arr.entries()) {
  if ( index === 5 ) break;
}

4
@superhero आप लूप के ... के लिए तत्व का इंडेक्स प्राप्त कर सकते हैं, आपको बस इसका उपयोग करना है entries। for (const [index, element] of someArray.entries ()) {// ...}
blackxored

यह सरणियों के साथ ... के लिए उपयोग नहीं करने की सिफारिश की है?
स्कैहता

4
@emostafa आप के लिए के बारे में सही कर रहे हैं में छोरों सरणियों के लिए अनुशंसित नहीं किया जा रहा है, लेकिन यह वास्तव में दृष्टिकोण है के लिए एक का उपयोग करता है के पाश।
कनक

यह "के लिए" है, और यह वास्तव में एक साफ समाधान है ... लेकिन यह भी एक ES6 सुविधा है, इसलिए बस यह ध्यान रखें कि यह तभी काम करेगा जब आपका वातावरण ES6 के लिए सेटअप हो।
चाड

मैं अपने आप को इस समाधान का उपयोग कर पाता हूं, और मैं इसे वस्तुओं के लिए भी उपयोग करता हूं। वस्तुओं के साथ, आप ऐसा कर सकते हैं Object.entries(myObject)और फिर इसका उपयोग ठीक उसी तरह कर सकते हैं जैसे आप for..inसरणी के लिए करते हैं। ध्यान दें कि JS सरणियाँ मूल रूप से हुड के नीचे की वस्तुएं हैं: blog.niftysnippets.org/2011/01/myth-of-arrays.html
एंड्रयू

204

आप हर विधि का उपयोग कर सकते हैं :

[1,2,3].every(function(el) {
    return !(el === 1);
});

ES6

[1,2,3].every( el => el !== 1 )

पुराने ब्राउज़र समर्थन उपयोग के लिए:

if (!Array.prototype.every)
{
  Array.prototype.every = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this &&
          !fun.call(thisp, this[i], i, this))
        return false;
    }

    return true;
  };
}

यहाँ अधिक जानकारी ।


10
[1,2,3].every( el => el !== 1 )
ईएस

1
@ वल्देमार, लेकिन क्या every गारंटी है कि कॉल अनुक्रम में किए गए हैं?
पेसियर

4
@ स्पेसियर, आप ईएस 6 विनिर्देश में एल्गोरिथ्म देख सकते हैं कि सूचकांक k0 से शुरू होता है और 1 से बढ़ जाता है: http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.every
XP1

@ XP1, क्या सभी कार्यान्वयनकर्ताओं को इसे करने की आवश्यकता है?
पचेरियर

1
@ स्पेसर, हाँ, सबसे लोकप्रिय कार्यान्वयन ठीक से काम करते हैं। यदि आप एम्बेडेड कार्यान्वयन के बारे में चिंतित हैं, तो आमतौर पर यह ओपेरा या वेबकिट है। आरोही क्रम में मौजूद प्रत्येक तत्व के लिए एक बार कॉलबैकफान की विधि, आरोही क्रम में , जब तक कि यह एक ऐसा स्थान न मिल जाए , जहां कॉलबैक गलत हो जाता है। चरण 7 को भी देखें। Let k be 0. और 8.e बढ़ाएँ k by 1.
Valdemar_Rudolfovich

78

MDN प्रलेखनArray.prototype.forEach() से उद्धरण :

नहीं है रोकने या तोड़ने के लिए कोई रास्ता नहीं एक forEach()एक अपवाद फेंक कर के अलावा अन्य पाश। यदि आपको इस तरह के व्यवहार की आवश्यकता है, तो .forEach()विधि गलत उपकरण है , इसके बजाय एक सादे लूप का उपयोग करें। यदि आप एक पूर्वनिर्धारित के लिए सरणी तत्वों का परीक्षण कर रहे हैं और एक बूलियन रिटर्न मान की आवश्यकता है, तो आप उपयोग कर सकते हैं every()या some()इसके बजाय।

आपके कोड के लिए (प्रश्न में), जैसा कि @bobince द्वारा सुझाया गया है, Array.prototype.some()इसके बजाय उपयोग करें । यह आपके usecase को बहुत अच्छी तरह से सूट करता है।

Array.prototype.some()सरणी में मौजूद प्रत्येक तत्व के लिए एक बार कॉलबैक फ़ंक्शन को निष्पादित करता है जब तक कि वह एक ऐसा न मिल जाए जहां कॉलबैक एक सत्य मान (एक मान जो तब परिवर्तित हो जाता है जब एक में परिवर्तित हो जाता है Boolean)। यदि ऐसा कोई तत्व पाया जाता है, तो some()तुरंत सच हो जाता है। नहीं तो some()झूठा लौट आता है। कॉलबैक केवल उसी सरणी के अनुक्रमित के लिए लागू किया जाता है जिसने मान असाइन किए हैं; यह उन अनुक्रमणिकाओं के लिए लागू नहीं किया गया है जिन्हें हटा दिया गया है या जिन्हें कभी भी असाइन नहीं किया गया है।


1
यह सही जवाब है। 'कुछ' ठीक वही करता है जो एक फोरचेक / ब्रेक करता है। यह छोर तक n = सत्य है।
एंटनी बूथ

74

दुर्भाग्य से इस मामले में यह बेहतर होगा यदि आप उपयोग नहीं करते हैं forEach। इसके बजाय एक नियमित forलूप का उपयोग करें और यह अब ठीक उसी तरह काम करेगा जैसे आप अपेक्षा करते हैं।

var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
  if (array[i] === 1){
    break;
  }
}

27
यह मुझे हैरान करता है कि उच्च प्रदर्शन, कम कोड, और इस सही उत्तर की बेहतर पठनीयता की तुलना में सबसे ज्यादा वोट संभव है। अपवाद फेंको ... सच में? क्या लूप के लिए पारंपरिक सिर्फ पर्याप्त नहीं है?
gdbj

2
@gdbj मैं आपके कथन से सहमत हूं और इस पद्धति का उपयोग किया है, लेकिन वास्तव में मुझे जो झटका लगा है, वह इन हैक के बिना किसी भी तरह से बाहर निकलने का कोई तरीका नहीं है, अब यह खराब डिजाइन है।
स्कॉट 11

28

उपयोग करने के लिए विचार करें jqueryकीeach , विधि के बाद से यह झूठी अंदर कॉलबैक फ़ंक्शन वापस जाने के लिए अनुमति देता है:

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

लोदाश लाइब्रेरी भी ऐसी takeWhileविधि प्रदान करती है जिसे मानचित्र / कम / गुना आदि के साथ जंजीर से जोड़ा जा सकता है:

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');
// => []

1
JQuery का उपयोग करने का अच्छा कारण। देशी जावास्क्रिप्ट में forach की अभी भी कमी है।
एलेक्स ग्रांडे

3
@AlexGrande jQuery के forEach और JavaScript के forEach संगत नहीं हैं।
ब्योर्न

10
जावास्क्रिप्ट का उपयोग कई स्थानों पर किया जाता है कि jQuery एक विकल्प नहीं है।
JBRWilkinson


18

यदि आप डीन एडवर्ड के सुझाव का उपयोग करना चाहते हैं और त्रुटि को पकड़ने के बिना लूप से बाहर निकलने के लिए StopIteration त्रुटि को फेंक सकते हैं, तो आप निम्न फ़ंक्शन ( मूल रूप से यहां से ) का उपयोग कर सकते हैं :

// Use a closure to prevent the global namespace from be polluted.
(function() {
  // Define StopIteration as part of the global scope if it
  // isn't already defined.
  if(typeof StopIteration == "undefined") {
    StopIteration = new Error("StopIteration");
  }

  // The original version of Array.prototype.forEach.
  var oldForEach = Array.prototype.forEach;

  // If forEach actually exists, define forEach so you can
  // break out of it by throwing StopIteration.  Allow
  // other errors will be thrown as normal.
  if(oldForEach) {
    Array.prototype.forEach = function() {
      try {
        oldForEach.apply(this, [].slice.call(arguments, 0));
      }
      catch(e) {
        if(e !== StopIteration) {
          throw e;
        }
      }
    };
  }
})();

उपरोक्त कोड आपको कोड चलाने की क्षमता देगा जैसे कि बिना अपनी कोशिश के क्लॉस करने के लिए निम्नलिखित:

// Show the contents until you get to "2".
[0,1,2,3,4].forEach(function(val) {
  if(val == 2)
    throw StopIteration;
  alert(val);
});

याद रखने वाली एक महत्वपूर्ण बात यह है कि यह केवल Array.prototype.forEach फ़ंक्शन को अपडेट करेगा यदि यह पहले से मौजूद है। यदि यह पहले से मौजूद नहीं है, तो यह इसे संशोधित नहीं करेगा।


11

संक्षिप्त उत्तर: इसके लिए उपयोग for...breakकरें या अपने कोड को बदलने से बचें forEach। उपयोग .some()या .every()अनुकरण करने के लिए नहीं for...breakfor...breakलूप, या उपयोग से बचने के लिए अपने कोड को फिर से लिखें for...break। हर बार जब आप इन तरीकों का इस्तेमाल करते हैं तो for...breakवैकल्पिक भगवान बिल्ली का बच्चा मारता है।

लंबा जवाब:

.some()और .every()दोनों वापसी booleanमूल्य, .some()रिटर्न trueअगर कोई तत्व है जिसके लिए पारित कर दिया समारोह रिटर्न true, हर रिटर्न falseअगर कोई तत्व है जिसके लिए पारित कर देता हैfalse । यही वह कार्य है जिसका अर्थ है। उनके मतलब के कार्यों का उपयोग करना बहुत बुरा है फिर सीएसएस के बजाय लेआउट के लिए तालिकाओं का उपयोग करना, क्योंकि यह हर उस व्यक्ति को निराश करता है जो आपके कोड को पढ़ता है।

इसके अलावा, for...breakविकल्प के रूप में इन तरीकों का उपयोग करने का एकमात्र संभव तरीका साइड-इफेक्ट्स ( .some()कॉलबैक फ़ंक्शन के बाहर कुछ संस्करण बदलना ) है, और यह इससे बहुत अलग नहीं है for...break

तो, का उपयोग कर .some()या .every()के रूप में for...breakपाश विकल्प दुष्प्रभाव से मुक्त नहीं है, यह अधिक स्वच्छ तो नहीं हैfor...break , यह निराशा होती है, इसलिए यह नहीं बेहतर है।

आप हमेशा अपने कोड को फिर से लिख सकते हैं ताकि इसमें कोई आवश्यकता न हो for...break। आप सरणी का उपयोग करके फ़िल्टर .filter()कर सकते हैं, आप सरणी का उपयोग कर विभाजित कर सकते हैं .slice()और इसी तरह, फिर उपयोग .forEach()या .map()सरणी के उस हिस्से के लिए।


.filter का उपयोग करना वास्तव में ब्रेकिंग के लिए बहुत सारे उपयोग के मामलों के लिए उपयुक्त समाधान है।
TKoL

प्रदर्शन के बारे में क्या? यदि अक्सर उपयोग किया जाता है तो Woudl't फ़िल्टर प्रदर्शन को प्रभावित करता है?
tfrascaroli

हां, फ़िल्टर सरणी प्रोटोटाइप भारी हो सकता है। मुझे यह पसंद है, लेकिन अगर इसका अत्यधिक उपयोग किया जाता है तो यह प्रदर्शन को प्रभावित कर सकता है।
चाड

for...breakयदि आपको प्रदर्शन की आवश्यकता है तो @tfrascaroli लूप का उपयोग करें । forपाश की तुलना में सबसे अधिक performant यात्रा उपकरण है .forEach(), .any(), .map(), .filter()आदि
मैक्स

6

यह सिर्फ कुछ है जो मैं इस समस्या को हल करने के लिए आया था ... मुझे पूरा यकीन है कि यह उस समस्या को हल करता है जो मूल पूछने वाले के पास थी:

Array.prototype.each = function(callback){
    if(!callback) return false;
    for(var i=0; i<this.length; i++){
        if(callback(this[i], i) == false) break;
    }
};

और तब आप इसका उपयोग करके कॉल करेंगे:

var myarray = [1,2,3];
myarray.each(function(item, index){
    // do something with the item
    // if(item != somecondition) return false; 
});

कॉलबैक फ़ंक्शन के अंदर गलत तरीके से लौटने पर ब्रेक का कारण होगा। मुझे पता है कि अगर वास्तव में काम नहीं करता है।


1
=== falseबेहतर हो सकता है == falseताकि आपको लूप को जारी रखने के लिए स्पष्ट रूप से सही (या एक सत्य मान) वापस न करना पड़े, ऐसा न हो कि कुछ नियंत्रण पथ का मान वापस न आए और लूप अनपेक्षित रूप से टूट जाए।
जेक

6

एक और अवधारणा जिसके साथ मैं आया था:

function forEach(array, cb) {
  var shouldBreak;
  function _break() { shouldBreak = true; }
  for (var i = 0, bound = array.length; i < bound; ++i) {
    if (shouldBreak) { break; }
    cb(array[i], i, array, _break);
  }
}

// Usage

forEach(['a','b','c','d','e','f'], function (char, i, array, _break) {
  console.log(i, char);
  if (i === 2) { _break(); }
});


वाक्य रचना [NSArray enumerateObjectsUsingBlock] के समान है, धन्यवाद!
Chrstph SLN

@ ड्रेनई हस्ताक्षर देशी के अनुरूप है Array.prototype.forEach()forऔर breakयह प्रश्न पूछे जाने से बहुत पहले से मौजूद था; ओपी उस व्यवहार की तलाश में था, जो अधिक कार्यात्मक हो forEach,।
c24w

@ ड्रेनई ने अब उनकी टिप्पणी को हटा दिया है (लेकिन नीचे छोड़ दिया है) जिसमें उल्लेख किया गया है कि इस समाधान के हस्ताक्षर को याद रखना मुश्किल है और अनावश्यक है जब आप समस्या को हल कर सकते हैं for...inऔर break
c24w

5

यह समाधान किसी अन्य साइट पर मिला। आप एक कोशिश / पकड़ परिदृश्य में 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/


2
नियंत्रण प्रवाह विवरणों के रूप में अपवादों का उपयोग न करें। अप्रत्याशित परिणामों से निपटने के लिए इसका उपयोग करें।
मैक्स


4

यदि आपको अपने सरणी को पुनरावृत्ति के बाद एक्सेस करने की आवश्यकता नहीं है, तो आप सरणी की लंबाई को 0. पर सेट करके जमानत कर सकते हैं। यदि आपको अपने पुनरावृत्ति के बाद भी इसकी आवश्यकता है, तो आप इसे स्लाइस का उपयोग करके क्लोन कर सकते हैं।

[1,3,4,5,6,7,8,244,3,5,2].forEach(function (item, index, arr) {
  if (index === 3) arr.length = 0;
});

या एक क्लोन के साथ:

var x = [1,3,4,5,6,7,8,244,3,5,2];

x.slice().forEach(function (item, index, arr) {
  if (index === 3) arr.length = 0;
});

जो आपके कोड में यादृच्छिक त्रुटियों को दूर करने के लिए एक बेहतर समाधान है।


अच्छी तरह से किया :) लेकिन अगर बताए के बाद कुछ कार्रवाई देखते हैं array.lengthकरने के लिए 0, वे वर्तमान चरण में लागू करेंगे जिससे शायद यह कभी कभी बेहतर उपयोग करने के लिए है returnके बाद इस तरह के बताए
zhibirc

4

यह लूप के लिए है, लेकिन लूप में ऑब्जेक्ट संदर्भ को फॉरएच () की तरह ही बनाए रखता है, लेकिन आप तोड़ सकते हैं।

var arr = [1,2,3];
for (var i = 0, el; el = arr[i]; i++) {
    if(el === 1) break;
}

4

जैसा कि पहले उल्लेख किया गया है, आप नहीं तोड़ सकते .forEach()

यहाँ ES6 Iterators के साथ एक फोरचेक करने का थोड़ा और आधुनिक तरीका है। आपको index/ तक सीधी पहुँच प्राप्त करने की अनुमति देता हैvalue पुनरावृत्त होने ।

const array = ['one', 'two', 'three'];

for (const [index, val] of array.entries()) {
  console.log('item:', { index, val });
  if (index === 1) {
    console.log('break!');
    break;
  }
}

आउटपुट:

item: { index: 0, val: 'one' }
item: { index: 1, val: 'two' }
break!

लिंक


3

फिर भी एक और दृष्टिकोण

        var wageType = types.filter(function(element){
            if(e.params.data.text == element.name){ 
                return element;
            }
        });
        console.dir(wageType);

2

मैं उस उद्देश्य के लिए nullhack का उपयोग करता हूं , यह उस संपत्ति का उपयोग करने की कोशिश करता है null, जो एक त्रुटि है:

try {
  [1,2,3,4,5]
  .forEach(
    function ( val, idx, arr ) {
      if ( val == 3 ) null.NULLBREAK;
    }
  );
} catch (e) {
  // e <=> TypeError: null has no properties
}
//

1
सिर्फ क्यों नहीं throw BREAK?
बरगी

1

अगर आप अपना रखना चाहते हैं forEach सिंटैक्स , तो यह इसे कुशल रखने का एक तरीका है (हालांकि लूप के लिए नियमित रूप से उतना अच्छा नहीं है)। एक चर के लिए तुरंत जांचें जो जानता है कि क्या आप लूप से बाहर निकलना चाहते हैं।

यह उदाहरण एक फ़ंक्शन स्कोप बनाने के लिए एक अनाम फ़ंक्शन का उपयोग करता है forEachजिसके चारों ओर आपको किए गए जानकारी को संग्रहीत करने की आवश्यकता होती है।

(function(){
    var element = document.getElementById('printed-result');
    var done = false;
    [1,2,3,4].forEach(function(item){
        if(done){ return; }
        var text = document.createTextNode(item);
        element.appendChild(text);
        if (item === 2){
          done = true;
          return;
        }
    });
})();
<div id="printed-result"></div>

मेरे दो सेंट।


1

मैं जानता हूं कि यह सही तरीका नहीं है। यह लूप को तोड़ना नहीं है। यह एक जुगाड़ है

let result = true;
[1, 2, 3].forEach(function(el) {
    if(result){
      console.log(el);
      if (el === 2){
        result = false;
      }
    }
});



0

@Bobince से सहमत, अपवित्र।

इसके अलावा, FYI करें:

इस उद्देश्य के लिए प्रोटोटाइप.js में कुछ है:

<script type="text/javascript">
  $$('a').each(function(el, idx) {
    if ( /* break condition */ ) throw $break;
    // do something
  });
</script>

$break आंतरिक रूप से "प्रत्येक" चक्र को तोड़ते हुए, लेकिन बाहरी त्रुटियों को उत्पन्न नहीं करते हुए, Prototyp.js द्वारा पकड़ा और संभाला जाएगा।

देखें Prototype.JS एपीआई जानकारी के लिए।

jQuery का भी एक तरीका है, बस लूप को जल्दी तोड़ने के लिए हैंडलर में झूठा लौटें:

<script type="text/javascript">
  jQuery('a').each( function(idx) {
    if ( /* break condition */ ) return false;
    // do something

  });
</script>

देखें jQuery एपीआई जानकारी के लिए।


0

यह सबसे कुशल नहीं है, क्योंकि आप अभी भी सभी तत्वों को चक्रित करते हैं, लेकिन मुझे लगा कि यह बहुत ही सरल विचार हो सकता है:

let keepGoing = true;
things.forEach( (thing) => {
  if (noMore) keepGoing = false;
  if (keepGoing) {
     // do things with thing
  }
});

continueएक कीवर्ड है, आपका कोड एक सिंटैक्स त्रुटि है।
बरगी १

3
यह देखते हुए कि आप वैसे भी ES6 का उपयोग कर रहे हैं, आपको बस एक for ofलूप में स्विच करना चाहिए और break;हमेशा की तरह।
बरगी १

फिक्स्ड, और सच - लेकिन ज्यादातर संक्षिप्तता के लिए es6 का उपयोग कर रहा था
शहीद

0

आप नीचे दिए गए कोड का अनुसरण कर सकते हैं जो मेरे लिए काम करता है:

 var     loopStop = false;
YOUR_ARRAY.forEach(function loop(){
    if(loopStop){ return; }
    if(condition){ loopStop = true; }
});

क्यों -1? यह एक अपवाद को पकड़ने की तुलना में बदसूरत नहीं है, यह एक बड़ा हैक IMHO है।
बायरन व्हिटलॉक

0

मैं उपयोग करना पसंद करता हूं for in

var words = ['a', 'b', 'c'];
var text = '';
for (x in words) {
    if (words[x] == 'b') continue;
    text += words[x];
}
console.log(text);

for inबहुत काम करता है forEach, और आप बाहर निकलने के समारोह में वापस जोड़ सकते हैं। बेहतर प्रदर्शन भी।


0

यदि आपको उन तत्वों के मूल्य के आधार पर तोड़ने की ज़रूरत है जो आपके मामले में पहले से ही हैं (जैसे कि यदि ब्रेक की स्थिति रन-टाइम चर पर निर्भर नहीं करती है जो सरणी के तत्व बदलने के बाद बदल सकती है) तो आप संयोजन का उपयोग भी कर सकते हैं का टुकड़ा () और indexOf () के रूप में इस प्रकार है।

अगर आपको तोड़ने की जरूरत है जब फॉरच 'एप्पल' तक पहुंचता है तो आप उपयोग कर सकते हैं

var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var fruitsToLoop = fruits.slice(0, fruits.indexOf("Apple"));
// fruitsToLoop = Banana,Orange,Lemon

fruitsToLoop.forEach(function(el) {
    // no need to break
});

जैसा कि W3Schools.com में कहा गया है कि स्लाइस () विधि एक नए सरणी ऑब्जेक्ट के रूप में चयनित तत्वों को एक सरणी में लौटाती है। मूल सरणी नहीं बदली जाएगी।

इसे JSFiddle में देखें

आशा है कि यह किसी की मदद करता है।


0

की आपको एक प्रकार बना सकते हैं forEachकि के लिए अनुमति देता है break, continue, return, और यहां तक async/ await: (उदाहरण के टाइपप्रति में लिखा)

export type LoopControlOp = "break" | "continue" | ["return", any];
export type LoopFunc<T> = (value: T, index: number, array: T[])=>LoopControlOp;

Array.prototype.ForEach = function ForEach<T>(this: T[], func: LoopFunc<T>) {
    for (let i = 0; i < this.length; i++) {
        const controlOp = func(this[i], i, this);
        if (controlOp == "break") break;
        if (controlOp == "continue") continue;
        if (controlOp instanceof Array) return controlOp[1];
    }
};

// this variant lets you use async/await in the loop-func, with the loop "awaiting" for each entry
Array.prototype.ForEachAsync = async function ForEachAsync<T>(this: T[], func: LoopFunc<T>) {
    for (let i = 0; i < this.length; i++) {
        const controlOp = await func(this[i], i, this);
        if (controlOp == "break") break;
        if (controlOp == "continue") continue;
        if (controlOp instanceof Array) return controlOp[1];
    }
};

उपयोग:

function GetCoffee() {
    const cancelReason = peopleOnStreet.ForEach((person, index)=> {
        if (index == 0) return "continue";
        if (person.type == "friend") return "break";
        if (person.type == "boss") return ["return", "nevermind"];
    });
    if (cancelReason) console.log("Coffee canceled because: " + cancelReason);
}

-1

"ढूंढें" के साथ प्रयास करें:

var myCategories = [
 {category: "start", name: "Start", color: "#AC193D"},
 {category: "action", name: "Action", color: "#8C0095"},
 {category: "exit", name: "Exit", color: "#008A00"}
];

function findCategory(category) {
  return myCategories.find(function(element) {
    return element.category === category;
  });
}

console.log(findCategory("start"));
// output: { category: "start", name: "Start", color: "#AC193D" }

-1

हां इसे जारी रखना और फॉरएच लूप से बाहर निकलना संभव है।

जारी रखने के लिए, आप रिटर्न का उपयोग कर सकते हैं, लूप जारी रहेगा लेकिन वर्तमान फ़ंक्शन समाप्त हो जाएगा।

लूप से बाहर निकलने के लिए, आप तीसरे पैरामीटर को 0 लंबाई में सेट कर सकते हैं, खाली सरणी पर सेट कर सकते हैं। लूप जारी नहीं रहेगा, वर्तमान फ़ंक्शन करता है, इसलिए आप "वापसी" का उपयोग कर सकते हैं, जैसे कि लूप के लिए सामान्य से बाहर निकलें ...

इस:

[1,2,3,4,5,6,7,8,9,10].forEach((a,b,c) => {
    console.log(a);
    if(b == 2){return;}
    if(b == 4){c.length = 0;return;}
    console.log("next...",b);
});

इसे प्रिंट करेंगे:

1
next... 0
2
next... 1
3
4
next... 3
5

-2

इससे पहले, मेरा कोड नीचे है

 this.state.itemsDataSource.forEach((item: any) => {
                if (!item.isByPass && (item.invoiceDate == null || item.invoiceNumber == 0)) {

                    return false;
                }
            });

मैं नीचे बदल गया हूं, यह तय हो गया था।

 for (var i = 0; i < this.state.itemsDataSource.length; i++) {
                var item = this.state.itemsDataSource[i];
                if (!item.isByPass && (item.invoiceDate == null || item.invoiceNumber == 0)) {

                    return false;
                }
            }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.