जावास्क्रिप्ट में नेस्टेड छोरों से तोड़ने का सबसे अच्छा तरीका क्या है?


448

जावास्क्रिप्ट में नेस्टेड छोरों से तोड़ने का सबसे अच्छा तरीका क्या है?

//Write the links to the page.
for (var x = 0; x < Args.length; x++)
{
   for (var Heading in Navigation.Headings)
   {
      for (var Item in Navigation.Headings[Heading])
      {
         if (Args[x] == Navigation.Headings[Heading][Item].Name)
         {
            document.write("<a href=\"" 
               + Navigation.Headings[Heading][Item].URL + "\">" 
               + Navigation.Headings[Heading][Item].Name + "</a> : ");
            break; // <---HERE, I need to break out of two loops.
         }
      }
   }
}

यहाँ छोरों से और कोड के ब्लॉकों से बाहर तोड़ने का अच्छा उदाहरण है: marcin-chwedczuk.github.io/…
csharpfolk

जवाबों:


1032

पर्ल की तरह,

loop1:
    for (var i in set1) {
loop2:
        for (var j in set2) {
loop3:
            for (var k in set3) {
                break loop2;  // breaks out of loop3 and loop2
            }
        }
    }

जैसा कि EMCA-262 खंड 12.12 में परिभाषित किया गया है। [एमडीएन डॉक्स]

सी के विपरीत, इन लेबल का उपयोग केवल continueऔर के लिए किया जा सकता है break, क्योंकि जावास्क्रिप्ट में नहीं है goto


387
WTF क्यों नहीं मैं जावास्क्रिप्ट के साथ अपने 3 साल में इस किया जा रहा है इस्तेमाल किया कहीं देखा है: / ..
सलमान वॉन अब्बास

39
एमडीएन का कहना है कि "लेबल का उपयोग करने से बचें" विशुद्ध रूप से पठनीयता के आधार पर। यह 'पठनीय' क्यों नहीं है? क्योंकि कोई भी उनका उपयोग नहीं करता है, निश्चित रूप से। लेकिन वे उनका उपयोग क्यों नहीं करते? ...
एक्सएमएल

7
@Web_Designer मेरा मानना ​​है कि आपकी टिप्पणी पुरानी है। एमडीएन डॉक्स में कहीं भी यह "लेबल का उपयोग करने से बचने" के लिए नहीं कहता है। कृपया अपनी टिप्पणी को संशोधित करने या हटाने पर विचार करें।
बीन

8
@ सीनियन बीन ने किया। यह अधिक स्पष्ट उत्तर की तरह लगता है और दुरुपयोग के लिए खुला नहीं है क्योंकि यह केवल continueऔर के लिए उपलब्ध है break
गैरी विल्बोबी

29
@ JérémyPouyet - डाउन वोटिंग के लिए आपका तर्क अयोग्य और अनुचित है। यह ओपी के सवाल का पूरी तरह से जवाब देता है। प्रश्न का संबंध सुगमता के संबंध में आपकी राय से नहीं है। कृपया समुदाय की सहायता के लिए अपने दृष्टिकोण पर पुनर्विचार करें।
दिम्बिंस्की

168

एक समारोह में लपेटें और फिर बस return


12
मैं इस उत्तर को स्वीकार करना चुनता हूं क्योंकि यह सरल है और इसे सुरुचिपूर्ण तरीके से लागू किया जा सकता है। मैं GOTO से बिलकुल नफरत करता हूं और उन्हें बुरा अभ्यास मानता हूं ( खोल सकता है ), Ephemient's भी एक के पास है। ; ओ)
गैरी विल्बोबी

16
IMO, GOTO तब तक ठीक होते हैं जब तक वे संरचना को नहीं तोड़ते। लेकिन प्रत्येक को उनके स्वयं के लिए!
०१० बजे

31
लूप के लिए लेबल पर उनके सिंटैक्स को छोड़कर GOTO के साथ कुछ भी सामान्य नहीं है। वे बस बाहरी छोरों से तोड़ने के लिए एक मामला है। आपको अंतरतम पाश को तोड़ने में कोई समस्या नहीं है, क्या आप? तो आपको बाहरी छोरों को तोड़ने में समस्या क्यों है?
जॉन स्मिथ

11
कृपया अन्य उत्तर को स्वीकार करने पर विचार करें। अगर एंड्रयू हेजेज टिप्पणी के लिए नहीं (धन्यवाद btw।), मैंने सोचा होगा: आह, इसलिए जावास्क्रिप्ट में वह सुविधा नहीं है। और मैं शर्त लगाता हूं कि समुदाय के कई लोग टिप्पणी को नजरअंदाज कर सकते हैं और सिर्फ एक ही सोच सकते हैं।
जॉन स्मिथ

11
स्टैक ओवरफ्लो के पास समुदाय को स्पष्ट रूप से गलत चयनित उत्तर को ओवरराइड करने की सुविधा क्यों नहीं है? : /
मैट हगिंस

85

मुझे पार्टी में थोड़ी देर हो गई है लेकिन निम्नलिखित एक भाषा-अज्ञेयवादी दृष्टिकोण है जो GOTO / लेबल या फ़ंक्शन रैपिंग का उपयोग नहीं करता है:

for (var x = Set1.length; x > 0; x--)
{
   for (var y = Set2.length; y > 0; y--)
   {
      for (var z = Set3.length; z > 0; z--)
      {
          z = y = -1; // terminates second loop
          // z = y = x = -1; // terminate first loop
      }
   }
}

उल्टा यह स्वाभाविक रूप से बहता है जिसे गैर-गोटो भीड़ को खुश करना चाहिए। नकारात्मक पक्ष पर, आंतरिक लूप को समाप्त करने से पहले वर्तमान पुनरावृत्ति को पूरा करने की आवश्यकता होती है, इसलिए यह कुछ परिदृश्यों में लागू नहीं हो सकता है।


2
उद्घाटन ब्रेस नई लाइनों पर नहीं होना चाहिए, क्योंकि जेएस कार्यान्वयन पूर्ववर्ती रेखा के अंत में एक बृहदान्त्र सम्मिलित कर सकता है।
एवगेनी

21
@ स्वदेशी: जबकि कुछ जावास्क्रिप्ट शैली के गाइड एक ही लाइन पर जाने के लिए ब्रेसिज़ खोलने का आह्वान करते हैं, नई लाइन पर इसे रखना गलत नहीं है और इंटरप्रेटर के अस्पष्ट रूप से अर्धविराम डालने का कोई खतरा नहीं है। एएसआई का व्यवहार अच्छी तरह से परिभाषित है और यहां लागू नहीं होता है।
जेसन सुआरेज़

9
बस इस दृष्टिकोण से नरक की टिप्पणी करना सुनिश्चित करें। यह तुरंत स्पष्ट नहीं है कि यहां क्या हो रहा है।
Qix - मोनासा 16

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

2
मैं कुछ गायब हो सकता है, लेकिन समाप्त करने के लिए हो रही है कि यात्रा आप एक में डाल सकता है भीतरी पाश की समस्या से बचने के लिए breakया continueके बाद आप सेट z और y तुरंत? मुझे forलूप की शर्तों का उपयोग करने का विचार पसंद है। अपने तरीके से सुरुचिपूर्ण।
बेन सटन

76

मुझे लगता है कि यह वास्तव में एक पुराना विषय है, लेकिन चूंकि मेरा मानक दृष्टिकोण अभी तक यहां नहीं है, इसलिए मुझे लगा कि मैं इसे भविष्य के गोगलर्स के लिए पोस्ट करूंगा।

var a, b, abort = false;
for (a = 0; a < 10 && !abort; a++) {
    for (b = 0; b < 10 && !abort; b++) {
        if (condition) {
            doSomeThing();
            abort = true;
        }
    }
}

2
यदि नेस्टेड लूप के पहले पुनरावृत्ति पर conditionमूल्यांकन किया जाता है true, तो आप अभी भी शेष 10 पुनरावृत्तियों के माध्यम से चलाते हैं, abortहर बार मान की जाँच करते हुए । यह 10 पुनरावृत्तियों के लिए एक प्रदर्शन समस्या नहीं है, लेकिन यह 10,000 के कहने के साथ होगा।
रोबस्टो

7
नहीं, यह दोनों छोरों से बाहर निकल रहा है। यहाँ प्रदर्शित फिडिंग है । कोई फर्क नहीं पड़ता कि आप किस शर्त को सेट करते हैं, यह मिलने के बाद बाहर निकल रहा है।
ज़ॉर्ड

4
अनुकूलन एक विराम जोड़ने के लिए होगा; गर्भपात के बाद = सही; और अंतिम लूप से गर्भपात की स्थिति की जांच।
15:21 बजे x2121

1
मुझे यह पसंद है, लेकिन मुझे लगता है कि एक सामान्य अर्थ में आप बहुत सारी अनावश्यक प्रसंस्करण करेंगे - अर्थात्, प्रत्येक पुनरावृत्ति मूल्यांकन abortऔर अभिव्यक्ति के प्रत्येक पुनरावृत्ति के लिए। सरल परिदृश्यों में, जो ठीक हो सकते हैं, लेकिन
गज़िल के

1
क्या आप लोग वास्तव में इस बात पर बहस कर रहे हैं कि क्या एक एकल बूलियन मूल्य की जाँच 10000 बार तेज या धीमी है? कोशिश 100 मिलियन बार / आह
fabspro

40
var str = "";
for (var x = 0; x < 3; x++) {
    (function() {  // here's an anonymous function
        for (var y = 0; y < 3; y++) {
            for (var z = 0; z < 3; z++) {
                // you have access to 'x' because of closures
                str += "x=" + x + "  y=" + y + "  z=" + z + "<br />";
                if (x == z && z == 2) {
                    return;
                }
            }
        }
    })();  // here, you execute your anonymous function
}

सो कैसे? :)


2
मुझे लगा कि यह क्या है स्वाइलियट्स मिल रहा था
harley.333

18
यह महत्वपूर्ण रनटाइम लागत को जोड़ता है यदि लूप बड़ा है - फ़ंक्शन के लिए एक नया निष्पादन संदर्भ (और जीसी द्वारा मुक्त किए गए कुछ बिंदु पर) इन दिनों जावास्क्रिप्ट इंटरप्रेटर / कंपाइलर (या, "कंप्रीटर" इन दिनों, दोनों का मिश्रण) होना चाहिए। हर बार।
मोरे

2
यह वास्तव में काफी खतरनाक है क्योंकि कुछ अजीब चीजें हो सकती हैं जो आप उम्मीद नहीं कर सकते हैं। विशेष रूप से, var के साथ बनाए गए क्लोजर के कारण x, यदि लूप के भीतर कोई लॉजिक बाद के समय में x को संदर्भित करता है (उदाहरण के लिए यह एक आंतरिक अनाम फ़ंक्शन को परिभाषित करता है जिसे बाद में सहेजा और निष्पादित किया जाता है), x के लिए मान जो भी होगा लूप के अंत में था, उस इंडेक्स को नहीं जिसे फ़ंक्शन के दौरान परिभाषित किया गया था। (
प्रतियोगिता

1
इसके आस-पास जाने के लिए, आपको xअपने अनाम फ़ंक्शन के पैरामीटर के रूप में पास करने की आवश्यकता है ताकि यह इसकी एक नई प्रति बनाए, जिसे तब बंद होने के रूप में संदर्भित किया जा सकता है क्योंकि यह उस बिंदु से नहीं बदलेगा। संक्षेप में, मैं ephemient के जवाब की सलाह देता हूं।
देवियो १

2
साथ ही, मुझे लगता है कि पठनीयता पूरी तरह से बकवास है। यह एक लेबल की तुलना में अधिक अस्पष्ट है। लेबल केवल अपठनीय के रूप में देखे जाते हैं क्योंकि कोई भी कभी भी उनका उपयोग नहीं करता है।
Qix - मोनासा

39

काफी सरल:

var a = [1, 2, 3];
var b = [4, 5, 6];
var breakCheck1 = false;

for (var i in a) {
    for (var j in b) {
        breakCheck1 = true;
        break;
    }
    if (breakCheck1) break;
}

मैं मानता हूं कि यह वास्तव में सबसे अच्छा है, फ़ंक्शन एक पैमाने पर नहीं है, सभी छोरों के लिए रैपिंग अगर यह भी स्केल नहीं करता है, तो इसे पढ़ना और डीबग करना कठिन हो जाता है .... यह एक बहुत बढ़िया है। आप बस वार्स लूप 1, लूप 2, लूप 3 की घोषणा कर सकते हैं, और अंत में थोड़ा स्टेटमेंट जोड़ सकते हैं। इसके अलावा कई छोरों को तोड़ने के लिए आपको कुछ करने की आवश्यकता होगी जैसेloop1=loop2=false;
मुहम्मद उमेर

22

यहाँ जावास्क्रिप्ट में नेस्टेड छोरों से बाहर निकलने के पांच तरीके दिए गए हैं:

1) माता-पिता को अंत में लूप सेट करें

for (i = 0; i < 5; i++)
{
    for (j = 0; j < 5; j++)
    {
        if (j === 2)
        {
            i = 5;
            break;
        }
    }
}

2) लेबल का उपयोग करें

exit_loops:
for (i = 0; i < 5; i++)
{
    for (j = 0; j < 5; j++)
    {
        if (j === 2)
            break exit_loops;
    }
}

3) चर का उपयोग करें

var exit_loops = false;
for (i = 0; i < 5; i++)
{
    for (j = 0; j < 5; j++)
    {
        if (j === 2)
        {
            exit_loops = true;
            break;
        }
    }
    if (exit_loops)
        break;
}

4) सेल्फ एक्जीक्यूटिंग फंक्शन का इस्तेमाल करें

(function()
{
    for (i = 0; i < 5; i++)
    {
        for (j = 0; j < 5; j++)
        {
             if (j === 2)
                 return;
        }
    }
})();

5) नियमित कार्य का उपयोग करें

function nested_loops()
{
    for (i = 0; i < 5; i++)
    {
        for (j = 0; j < 5; j++)
        {
             if (j === 2)
                 return;
        }
    }
}
nested_loops();

1
@Wyck मैं पर्याप्त सहमत नहीं हो सकता! यह शर्म की बात है कि जावास्क्रिप्ट में सिर्फ़ एक वाक्यविन्यास नहीं है break 2;जैसा कि हमारे पास है। कोई लूप लेबल नहीं, कोई फ़ंक्शंस नहीं, कोई और-तो चेक नहीं, लूप वेरिएबल के साथ कोई तड़का नहीं - बस साफ सिंटैक्स!
जय दादानिया

1
उदाहरण 4 निफ्टी है
leroyjenkinss24

14

कैसे के बारे में कोई ब्रेक का उपयोग कर, कोई गर्भपात झंडे, और कोई अतिरिक्त स्थिति की जाँच करता है। यह संस्करण बस लूप वैरिएबल को ब्लास्ट करता है ( Number.MAX_VALUEजब उन्हें बनाता है ) जब शर्त पूरी हो जाती है और सभी छोरों को सुरुचिपूर्ण ढंग से समाप्त करने के लिए मजबूर करता है।

// No breaks needed
for (var i = 0; i < 10; i++) {
  for (var j = 0; j < 10; j++) {
    if (condition) {
      console.log("condition met");
      i = j = Number.MAX_VALUE; // Blast the loop variables
    }
  }
}

डिक्रिप्टिंग-टाइप नेस्टेड लूप के लिए एक समान-ईश उत्तर था, लेकिन यह सरल लूप के लिए प्रत्येक लूप की समाप्ति मूल्य पर विचार करने की आवश्यकता के बिना एनग्रेड लूप को बढ़ाने के लिए काम करता है।

एक और उदाहरण:

// No breaks needed
for (var i = 0; i < 89; i++) {
  for (var j = 0; j < 1002; j++) {
    for (var k = 0; k < 16; k++) {
      for (var l = 0; l < 2382; l++) {
        if (condition) {
          console.log("condition met");
          i = j = k = l = Number.MAX_VALUE; // Blast the loop variables
        }
      }
    }
  }
}

4

कैसे छोरों को उनकी अंतिम सीमा तक धकेलने के बारे में

    for(var a=0; a<data_a.length; a++){
       for(var b=0; b<data_b.length; b++){
           for(var c=0; c<data_c.length; c++){
              for(var d=0; d<data_d.length; d++){
                 a =  data_a.length;
                 b =  data_b.length;
                 c =  data_b.length;
                 d =  data_d.length;
            }
         }
       }
     }

1
मुझे लगता है कि ड्रेक्स के जवाब में एक ही तर्क अधिक रसीला और स्पष्ट तरीके से है।
इंजीनियर टोस्ट

बिल्कुल प्रतिभाशाली!
जियोय्स

3

यदि आप कॉफ़ीस्क्रिप्ट का उपयोग करते हैं, तो एक सुविधाजनक "डू" कीवर्ड है जो इसे परिभाषित करना आसान बनाता है और तुरंत एक अनाम फ़ंक्शन को निष्पादित करता है:

do ->
  for a in first_loop
    for b in second_loop
      if condition(...)
        return

... ताकि आप छोरों से बाहर निकलने के लिए बस "वापसी" का उपयोग कर सकें।


यह वही नहीं है। मेरे मूल उदाहरण में forदो नहीं बल्कि तीन छोरें हैं।
गैरी विलोबी

2

मैंने सोचा कि मैं एक कार्यात्मक-प्रोग्रामिंग दृष्टिकोण दिखाऊंगा। आप मेरे समाधान के अनुसार नेस्टेड Array.prototype.some () और / या Array.prototyp.every () फ़ंक्शन से बाहर निकल सकते हैं। इस दृष्टिकोण का एक अतिरिक्त लाभ यह है कि Object.keys()केवल एक वस्तु के स्वयं के गुणों की गणना की जाती है, जबकि "फॉर-इन लूप प्रोटोटाइप श्रृंखला में गुणों की गणना करता है"

ओपी के समाधान के करीब:

    Args.forEach(function (arg) {
        // This guard is not necessary,
        // since writing an empty string to document would not change it.
        if (!getAnchorTag(arg))
            return;

        document.write(getAnchorTag(arg));
    });

    function getAnchorTag (name) {
        var res = '';

        Object.keys(Navigation.Headings).some(function (Heading) {
            return Object.keys(Navigation.Headings[Heading]).some(function (Item) {
                if (name == Navigation.Headings[Heading][Item].Name) {
                    res = ("<a href=\""
                                 + Navigation.Headings[Heading][Item].URL + "\">"
                                 + Navigation.Headings[Heading][Item].Name + "</a> : ");
                    return true;
                }
            });
        });

        return res;
    }

समाधान जो शीर्षकों / वस्तुओं पर पुनरावृत्ति को कम करता है:

    var remainingArgs = Args.slice(0);

    Object.keys(Navigation.Headings).some(function (Heading) {
        return Object.keys(Navigation.Headings[Heading]).some(function (Item) {
            var i = remainingArgs.indexOf(Navigation.Headings[Heading][Item].Name);

            if (i === -1)
                return;

            document.write("<a href=\""
                                         + Navigation.Headings[Heading][Item].URL + "\">"
                                         + Navigation.Headings[Heading][Item].Name + "</a> : ");
            remainingArgs.splice(i, 1);

            if (remainingArgs.length === 0)
                return true;
            }
        });
    });

2

पहले से ही उल्लुओं द्वारा पहले से ही उल्लेख किया गया है , लेकिन नीचे एक उदाहरण (जावास्क्रिप्ट) के साथ:

// Function wrapping inner for loop
function CriteriaMatch(record, criteria) {
  for (var k in criteria) {
    if (!(k in record))
      return false;

    if (record[k] != criteria[k])
      return false;
  }

  return true;
}

// Outer for loop implementing continue if inner for loop returns false
var result = [];

for (var i = 0; i < _table.length; i++) {
  var r = _table[i];

  if (!CriteriaMatch(r[i], criteria))
    continue;

  result.add(r);
}

0

10 साल पुरानी पार्टी में हम्मम?

कुछ शर्त क्यों नहीं लगाई?

var condition = true
for (var i = 0 ; i < Args.length && condition ; i++) {
    for (var j = 0 ; j < Args[i].length && condition ; j++) {
        if (Args[i].obj[j] == "[condition]") {
            condition = false
        }
    }
}

इस तरह आप जब चाहें तब रुक जाते हैं

मेरे मामले में, टाइपस्क्रिप्ट का उपयोग करते हुए, हम कुछ का उपयोग कर सकते हैं () जो कि सरणी से गुजरते हैं और जब स्थिति पूरी हो जाती है तो रुक जाते हैं इसलिए मेरा कोड इस तरह हो जाता है:

Args.some((listObj) => {
    return listObj.some((obj) => {
        return !(obj == "[condition]")
    })
})

इस तरह, हालत ठीक होने के बाद लूप बंद हो गया

अनुस्मारक: यह कोड टाइपस्क्रिप्ट में चलता है


-3
XXX.Validation = function() {
    var ok = false;
loop:
    do {
        for (...) {
            while (...) {
                if (...) {
                    break loop; // Exist the outermost do-while loop
                }
                if (...) {
                    continue; // skips current iteration in the while loop
                }
            }
        }
        if (...) {
            break loop;
        }
        if (...) {
            break loop;
        }
        if (...) {
            break loop;
        }
        if (...) {
            break loop;
        }
        ok = true;
        break;
    } while(true);
    CleanupAndCallbackBeforeReturning(ok);
    return ok;
};

9
यह अधिक भ्रामक लगता है तब मूल।
क्रिस्टियानो फोंट

21
उत्तर-आधुनिक कविता की तरह
दिगकर्म

वोट किया गया क्योंकि इस प्रकार के परिदृश्य में (ज्यादातर मामलों में) अधिक हो रहा है।
कोडी

-4

सबसे अच्छा तरीका है -
1) दोनों सरणी को क्रमबद्ध करें जो पहले और दूसरे लूप में उपयोग की जाती हैं।
2) यदि आइटम मेल खाता है, तो आंतरिक लूप को तोड़ें और इंडेक्स मान को रोकें।
3) जब अगला चलना शुरू करें तो इंडेक्स लूप को होल्ड इंडेक्स वैल्यू के साथ शुरू करें।

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