जावास्क्रिप्ट में एक सरणी पर प्रत्येक के लिए


4681

मैं जावास्क्रिप्ट का उपयोग करके किसी सरणी में सभी प्रविष्टियों के माध्यम से कैसे लूप कर सकता हूं?

मैंने सोचा कि यह कुछ इस तरह था:

forEach(instance in theArray)

theArrayमेरी सरणी कहां है, लेकिन यह गलत प्रतीत होता है।


16
मैंने इसके लिए तलाश की, लेकिन मैंने तलाश की forEach और सिर्फ नहीं for। जैसा कि कहा गया है, c # में यह थोड़ा अलग था, और
इसने

6
ECMAScript & nbsp; 6 में संभवतः "for ..." का निर्माण होगा। अधिक जानकारी के लिए (MDN) देखें ... आप हाल ही में फ़ायरफ़ॉक्स संस्करणों के साथ इसे आज़मा सकते हैं।
स्लावेन रेज़िक

35
Array.ForEach जावास्क्रिप्ट में Arrays के लिए प्रत्येक के लिए () की तुलना में लगभग 95% धीमा है। इस प्रदर्शन की परीक्षा ऑनलाइन देखें: jsperf.com/fast-array-foreach via coderwall.com/p/kvzbpa
molokoloco

77
कई स्थितियों के लिए जो 95% धीमी गति से महत्वपूर्ण ब्लॉग
डेविड साइक्स

7
इसके विपरीत, में अजगर यह है और अधिक कुशल उपयोग छोरों के लिए पारंपरिक की तुलना में कार्यों का उपयोग करने के लिए। (विचार करें कि i < lenऔर i++दुभाषिया के बजाय इंजन द्वारा किया जा सकता है।)
joeytwiddle

जवाबों:


7017

टी एल; डॉ

  • for-inजब तक आप इसे सुरक्षा उपायों के साथ उपयोग नहीं करते हैं या कम से कम इस बात से अवगत नहीं हैं कि यह आपको क्यों काट सकता है।
  • आपके सर्वश्रेष्ठ दांव आमतौर पर होते हैं

    • एक for-ofलूप (ES2015 + केवल),
    • Array#forEach( spec| MDN) (या उसके रिश्तेदारों someऔर इस तरह) (ES5 + केवल),
    • एक साधारण पुराने जमाने का forलूप,
    • या for-inसुरक्षा उपायों के साथ।

लेकिन वहाँ बहुत अधिक का पता लगाने के लिए, पर पढ़ें ...


जावास्क्रिप्ट में सरणियों और सरणी जैसी वस्तुओं के माध्यम से लूपिंग के लिए शक्तिशाली शब्दार्थ है। मैंने उत्तर को दो भागों में विभाजित किया है: वास्तविक सरणियों के लिए विकल्प, और उन चीजों के लिए विकल्प जो सिर्फ सरणी हैं - जैसे कि argumentsवस्तु, जैसे अन्य पुनरावृत्त वस्तुएं (ES2015 +), DOM संग्रह, और इसी तरह।

मैं जल्दी से ध्यान देता हूं कि आप ES5 इंजन का उपयोग कर सकते हैं , यहां तक ​​कि ES5 इंजन पर भी, ES2015 को ES5 पर ट्रांसप्लान कर सकते हैं। अधिक के लिए "ES2015 ट्रांसपिलिंग" / "ईएस 6 ट्रांसपिलिंग" खोजें ...

ठीक है, चलो हमारे विकल्प देखें:

वास्तविक एरे के लिए

आपके पास ECMAScript 5 ("ES5") में तीन विकल्प हैं , जो इस समय सबसे व्यापक रूप से समर्थित है, और ECMAScript 2015 ("ES2015", "ES6") में दो और जोड़े गए हैं :

  1. उपयोग forEachऔर संबंधित (ES5 +)
  2. एक साधारण forलूप का उपयोग करें
  3. सही ढंग से उपयोग करेंfor-in
  4. का उपयोग करें for-of(एक iterator निहितार्थ का उपयोग करें ) (ES2015 +)
  5. स्पष्ट रूप से एक इटरेटर का उपयोग करें (ES2015 +)

विवरण:

1. उपयोग forEachऔर संबंधित

किसी भी अस्पष्ट-आधुनिक वातावरण में (इसलिए, IE8 नहीं) जहां आपके पास ArrayES5 द्वारा जोड़ी गई सुविधाओं तक पहुंच है (सीधे या पॉलीफिल्स का उपयोग करके), आप उपयोग कर सकते हैं forEach( spec| MDN):

var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});

forEachकॉलबैक फ़ंक्शन को स्वीकार करता है और वैकल्पिक रूप से, thisउस कॉलबैक को कॉल करते समय उपयोग करने के लिए एक मान (ऊपर उपयोग नहीं किया गया)। कॉलबैक को सरणी में प्रत्येक प्रविष्टि के लिए कहा जाता है, आदेश में, विरल सरणियों में गैर-मौजूद प्रविष्टियों को लंघन। हालाँकि मैंने ऊपर केवल एक तर्क का उपयोग किया था, कॉलबैक को तीन के साथ कहा जाता है: प्रत्येक प्रविष्टि का मूल्य, उस प्रविष्टि का सूचकांक, और उस सरणी का संदर्भ जो आप अपने कार्य से पहले ही इसे संभाल नहीं पा रहे हैं )।

जब तक आप IE8 जैसे अप्रचलित ब्राउज़रों का समर्थन नहीं कर रहे हैं (जो NetApps सितंबर 2016 में इस लेखन के रूप में केवल 4% से अधिक बाजार हिस्सेदारी पर दिखाता है), तो आप forEachबिना शर्म किए सामान्य रूप से सामान्य वेब पेज में उपयोग कर सकते हैं । यदि आपको अप्रचलित ब्राउज़रों का समर्थन करने की आवश्यकता है, तो shimming / polyfilling forEachआसानी से किया जाता है (कई विकल्पों के लिए "es5 शिम" की खोज करें)।

forEach लाभ यह है कि आपको अनुक्रमणिका और मूल्य चर को घोषित दायरे में घोषित करने की आवश्यकता नहीं है, क्योंकि वे पुनरावृत्ति फ़ंक्शन के तर्क के रूप में आपूर्ति किए जाते हैं, और इसलिए केवल उस पुनरावृत्ति के लिए अच्छी तरह से scoped।

यदि आप प्रत्येक सरणी प्रविष्टि के लिए फ़ंक्शन कॉल करने के रनटाइम लागत के बारे में चिंतित हैं, तो मत बनो; विवरण

इसके अतिरिक्त, forEach"उन सभी के माध्यम से लूप" फ़ंक्शन है, लेकिन ES5 ने कई अन्य उपयोगी परिभाषित किए हैं "अपने तरीके से सरणी के माध्यम से काम करें और" कार्य करें, जिनमें शामिल हैं:

  • every(कॉलबैक रिटर्न falseया किसी चीज़ को पहली बार लूप करना बंद कर देता है )
  • some(कॉलबैक रिटर्न trueया कुछ सच होने पर पहली बार लूप बंद करना)
  • filter(उन तत्वों को शामिल करता है, जिनमें फ़िल्टर फ़ंक्शन लौटता है trueऔर जहाँ वह वापस लौटता है, उन्हें छोड़ता है false)
  • map (कॉलबैक द्वारा दिए गए मानों से एक नई सरणी बनाता है)
  • reduce (कॉलबैक को बार-बार कॉल करके, पिछले मानों में पास करके एक मान बनाता है; विवरण के लिए युक्ति देखें; एक सरणी की सामग्री और कई अन्य चीजों के लिए उपयोगी है)
  • reduceRight(जैसे reduce, लेकिन आरोही क्रम के बजाय अवरोही में काम करता है)

2. एक साधारण forलूप का उपयोग करें

कभी-कभी पुराने तरीके सबसे अच्छे होते हैं:

var index;
var a = ["a", "b", "c"];
for (index = 0; index < a.length; ++index) {
    console.log(a[index]);
}

यदि लूप के दौरान ऐरे की लंबाई नहीं बदलेगी, और यह प्रदर्शन-संवेदनशील कोड (असंभावित) में है, तो सामने की ओर लंबाई को पकड़े हुए थोड़ा अधिक जटिल संस्करण एक छोटा सा तेज़ हो सकता है :

var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}

और / या पीछे की गिनती:

var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}

लेकिन आधुनिक जावास्क्रिप्ट इंजन के साथ, यह दुर्लभ है कि आपको रस के अंतिम बिट को बाहर निकालने की आवश्यकता है।

ES2015 और उच्चतर में, आप अपने सूचकांक और मान को forलूप में स्थानीय बना सकते हैं :

let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
    console.log(index, value);
}
//console.log(index);   // would cause "ReferenceError: index is not defined"
//console.log(value);   // would cause "ReferenceError: value is not defined"

और जब आप ऐसा करते हैं, तो न केवल, valueबल्कि indexप्रत्येक लूप पुनरावृत्ति के लिए फिर से बनाया जाता है, जिसका अर्थ है लूप बॉडी में निर्मित क्लोजर उस विशिष्ट पुनरावृत्ति के लिए बनाए गए index(और value) का संदर्भ रखते हैं :

let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        console.log("Index is: " + index);
    });
}

यदि आपके पास पाँच विभाग हैं, तो आपको "सूचकांक है: 0" यदि आपने पहले क्लिक किया है और "सूचकांक है: 4" यदि आपने अंतिम क्लिक किया है। यदि आप इसके बजाय उपयोग करते हैं तो यह काम नहीं करता varहै let

3. सही ढंग से उपयोग करेंfor-in

आप लोगों से कहेंगे कि आप इसका इस्तेमाल करें for-in, लेकिन ऐसा नहीं for-inहैकिसी वस्तुfor-in के असंख्य गुणों के माध्यम से लूप्स , न कि किसी सरणी के अनुक्रमित। आदेश की गारंटी नहीं है , ES2015 (ES6) में भी नहीं। ES2015 + एक आदेश को गुण के माध्यम से परिभाषित करता है (के माध्यम से [[OwnPropertyKeys]], [[Enumerate]]और उन चीजों का उपयोग करता है जो उन्हें पसंद करते हैं Object.getOwnPropertyKeys), लेकिन यह परिभाषित नहीं किया कि for-inउस आदेश का पालन करेगा; ES2020, हालांकि किया। ( इस अन्य उत्तर में विवरण ।)

for-inकिसी सरणी पर केवल वास्तविक उपयोग के मामले हैं:

  • यह बड़े पैमाने पर अंतराल के साथ एक विरल सरणियाँ है, या
  • आप गैर-तत्व गुणों का उपयोग कर रहे हैं और आप उन्हें लूप में शामिल करना चाहते हैं

केवल उस पहले उदाहरण को देखते हुए: for-inयदि आप उचित सुरक्षा उपायों का उपयोग करते हैं, तो आप उन विरल सरणी तत्वों की यात्रा कर सकते हैं :

// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These checks are
        /^0$|^[1-9]\d*$/.test(key) &&    // explained
        key <= 4294967294                // below
        ) {
        console.log(a[key]);
    }
}

तीन जाँचों पर ध्यान दें:

  1. वस्तु अपनी नहीं है यही कारण है कि खुद उस नाम (नहीं एक यह अपने प्रोटोटाइप से विरासत), और से संपत्ति

  2. यह कुंजी सभी दशमलव अंक हैं (उदाहरण के लिए, सामान्य स्ट्रिंग रूप, वैज्ञानिक संकेतन नहीं), और

  3. यह महत्वपूर्ण है कि जब किसी संख्या के लिए मजबूर किया जाता है, तो <= 2 ^ 32 - 2 (जो 4,294,967,294 है)। वह संख्या कहां से आती है? यह विनिर्देश में एक सरणी सूचकांक की परिभाषा का हिस्सा है । अन्य संख्याएँ (गैर-पूर्णांक, ऋणात्मक संख्याएँ, 2 ^ 32 - 2 से अधिक संख्याएँ) सरणी अनुक्रमणिका नहीं हैं। इसका कारण 2 ^ 32 - 2 है, जो कि सबसे बड़ी इंडेक्स वैल्यू को 2 ^ 32 - 1 से कम बनाता है , जो एक एरे का अधिकतम मूल्य lengthहो सकता है। (उदाहरण के लिए, एक सरणी की लंबाई 32-बिट अहस्ताक्षरित पूर्णांक में फिट होती है।) ( मेरे ब्लॉग पोस्ट पर एक टिप्पणी में इंगित करने के लिए RobG के लिए प्रॉप्स कि मेरा पिछला परीक्षण बिल्कुल सही नहीं था।)

आप निश्चित रूप से इनलाइन कोड नहीं करेंगे। आप एक उपयोगिता फ़ंक्शन लिखेंगे। शायद:

4. for-of(इम्परेटर का उपयोग करें ) (ES2015 +) का उपयोग करें

ES2015 जोड़ा iterators जावास्क्रिप्ट को। पुनरावृत्तियों का उपयोग करने का सबसे आसान तरीका नया for-ofकथन है। यह इस तरह दिख रहा है:

const a = ["a", "b", "c"];
for (const val of a) {
    console.log(val);
}

कवर के तहत, यह सरणी से एक पुनरावृत्ति प्राप्त करता है और इसके माध्यम से लूप करता है, इससे मान प्राप्त करता है। इसका उपयोग करने वाले समस्या के पास नहीं for-inहै, क्योंकि यह ऑब्जेक्ट (सरणी) द्वारा परिभाषित एक पुनरावृत्ति का उपयोग करता है, और सरणियों को परिभाषित करता है कि उनके पुनरावृत्तियों उनकी प्रविष्टियों के माध्यम से पुनरावृति करते हैं (उनके गुणों को नहीं)। for-inES5 के विपरीत , जिस क्रम में प्रविष्टियों का दौरा किया जाता है वह उनके अनुक्रमित का संख्यात्मक क्रम है।

5. स्पष्ट रूप से एक पुनरावृत्ति का उपयोग करें (ES2015 +)

कभी-कभी, आप इट्रेटर का उपयोग स्पष्ट रूप से करना चाह सकते हैं । आप यह भी कर सकते हैं, हालांकि, यह बहुत अधिक क्लिंकर है for-of। यह इस तरह दिख रहा है:

const a = ["a", "b", "c"];
const it = a.values();
let entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}

इटरेटर विनिर्देश में Iterator परिभाषा से मेल खाती एक वस्तु है। हर बार जब आप इसे कहते हैं, तो इसका nextतरीका एक नई परिणाम वस्तु देता है। परिणाम वस्तु में एक संपत्ति होती है, doneजो हमें बताती है कि क्या यह किया गया है, और valueउस पुनरावृत्ति के लिए एक संपत्ति है । ( doneवैकल्पिक है अगर यह होगा false, valueवैकल्पिक है अगर यह होगा undefined।)

valueइटरेटर के आधार पर भिन्नता का अर्थ ; एरियर्स समर्थन (कम से कम) तीन कार्य जो पुनरावृत्तियाँ लौटाते हैं:

  • values(): यह वही है जिसका मैंने ऊपर प्रयोग किया है। यह एक इटरेटर जहां प्रत्येक रिटर्न valueकि यात्रा के लिए सरणी प्रविष्टि है ( "a", "b", और "c"उदाहरण के पहले में)।
  • keys(): रिटर्न पुनरावर्तक जहां प्रत्येक valueकि यात्रा के लिए महत्वपूर्ण है (ताकि हमारे लिए aऊपर, कि हो सकता है "0", तो "1", तो "2")।
  • entries(): एक पुनरावृत्ति देता है जहाँ प्रत्येक उस पुनरावृत्ति के लिए valueएक सरणी है [key, value]

एरे-लाइक ऑब्जेक्ट के लिए

वास्तविक सरणियों के अलावा, ऐसी सरणी- वस्तुएं भी हैं जिनके पास lengthसंख्यात्मक नाम के साथ एक संपत्ति और गुण हैं: NodeListउदाहरण, argumentsऑब्जेक्ट, आदि हम उनकी सामग्री के माध्यम से कैसे लूप करते हैं?

सरणियों के लिए ऊपर दिए गए किसी भी विकल्प का उपयोग करें

कम से कम कुछ, और संभवतः सबसे अधिक या यहां तक ​​कि सभी, ऊपर दिए गए एरे दृष्टिकोण के समान एरे जैसी वस्तुओं पर समान रूप से लागू होते हैं:

  1. उपयोग forEachऔर संबंधित (ES5 +)

    विभिन्न कार्य Array.prototype"जानबूझकर सामान्य" हैं और आमतौर पर सरणी जैसी वस्तुओं पर Function#callया के माध्यम से उपयोग किया जा सकता है Function#apply। ( इस उत्तर के अंत में होस्ट-प्रदान की गई वस्तुओं के लिए कैविएट देखें , लेकिन यह एक दुर्लभ मुद्दा है।)

    आप उपयोग करना चाहता था मान लीजिए forEachएक पर Nodeकी childNodesसंपत्ति। आप ऐसा करेंगे:

    Array.prototype.forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });

    यदि आप ऐसा करने जा रहे हैं, तो आप पुन: उपयोग के लिए एक चर में फ़ंक्शन संदर्भ की एक प्रति हड़पना चाहते हैं, जैसे:

    // (This is all presumably in some scoping function)
    var forEach = Array.prototype.forEach;
    
    // Then later...
    forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
  2. एक साधारण forलूप का उपयोग करें

    जाहिर है, एक साधारण forलूप सरणी जैसी वस्तुओं पर लागू होता है।

  3. सही ढंग से उपयोग करेंfor-in

    for-inएक सरणी के साथ एक ही सुरक्षा उपायों के साथ सरणी जैसी वस्तुओं के साथ भी काम करना चाहिए; उपरोक्त # 1 पर होस्ट-प्रदान की गई वस्तुओं के लिए चेतावनी लागू हो सकती है।

  4. का उपयोग करें for-of(एक iterator निहितार्थ का उपयोग करें ) (ES2015 +)

    for-ofवस्तु (यदि कोई है) द्वारा प्रदान किए गए पुनरावृत्ति का उपयोग करता है । जिसमें होस्ट-प्रदत्त ऑब्जेक्ट शामिल हैं। उदाहरण के लिए, के लिए विनिर्देश NodeListसे querySelectorAllयात्रा का समर्थन करने के अद्यतन किया गया था। के लिए कल्पना HTMLCollectionसे getElementsByTagNameनहीं था।

  5. स्पष्ट रूप से एक इटरेटर का उपयोग करें (ES2015 +)

    # 4 देखें।

एक सच्ची सरणी बनाएँ

दूसरी बार, आप एक सरणी जैसी वस्तु को एक सच्चे सरणी में बदलना चाहते हैं। ऐसा करना आश्चर्यजनक रूप से आसान है:

  1. sliceसरणियों की विधि का उपयोग करें

    हम sliceसरणियों की विधि का उपयोग कर सकते हैं , जो ऊपर बताए गए अन्य तरीकों की तरह "जानबूझकर सामान्य" है और इसलिए इसका उपयोग सरणी जैसी वस्तुओं के साथ किया जा सकता है:

    var trueArray = Array.prototype.slice.call(arrayLikeObject);

    उदाहरण के लिए, यदि हम NodeListएक वास्तविक सरणी में बदलना चाहते हैं, तो हम ऐसा कर सकते हैं:

    var divs = Array.prototype.slice.call(document.querySelectorAll("div"));

    होस्ट-प्रदान की गई वस्तुओं के लिए कैविएट देखें । विशेष रूप से, ध्यान दें कि यह IE8 और इससे पहले में विफल हो जाएगा, जो आपको होस्ट-प्रदान की गई वस्तुओं का उपयोग करने की अनुमति नहीं देता thisहै।

  2. स्प्रेड सिंटैक्स ( ...) का उपयोग करें

    जावास्क्रिप्ट इंजनों के साथ ES2015 के प्रसार सिंटैक्स का उपयोग करना भी संभव है जो इस सुविधा का समर्थन करते हैं। जैसे for-of, यह ऑब्जेक्ट द्वारा प्रदान किए गए पुनरावृत्ति का उपयोग करता है (पिछले अनुभाग में # 4 देखें):

    var trueArray = [...iterableObject];

    उदाहरण के लिए, यदि हम NodeListएक वास्तविक सरणी में बदलना चाहते हैं, तो प्रसार सिंटैक्स के साथ यह काफी सफल हो जाता है:

    var divs = [...document.querySelectorAll("div")];
  3. उपयोग Array.from

    Array.from (कल्पना) | (MDN) (ES2015 +, लेकिन आसानी से पॉलीफ़िल्ड) एक सरणी जैसी ऑब्जेक्ट से एक सरणी बनाता है, वैकल्पिक रूप से पहले एक मैपिंग फ़ंक्शन के माध्यम से प्रविष्टियों को पास करना। इसलिए:

    var divs = Array.from(document.querySelectorAll("div"));

    या यदि आप दिए गए वर्ग के साथ तत्वों के टैग नामों की एक सरणी प्राप्त करना चाहते हैं, तो आप मैपिंग फ़ंक्शन का उपयोग करेंगे:

    // Arrow function (ES2015):
    var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName);
    
    // Standard function (since `Array.from` can be shimmed):
    var divs = Array.from(document.querySelectorAll(".some-class"), function(element) {
        return element.tagName;
    });

मेजबान प्रदान की वस्तुओं के लिए चेतावनी

यदि आप होस्ट-प्रदान की गई सरणी जैसी ऑब्जेक्ट्स (जावास्क्रिप्ट सूचियों और जावास्क्रिप्ट इंजन के बजाय ब्राउज़र द्वारा प्रदान की गई अन्य चीजें) के Array.prototypeसाथ फ़ंक्शंस का उपयोग करते हैं , तो आपको यह सुनिश्चित करने की ज़रूरत है कि होस्ट-प्रदान की गई वस्तु ठीक से व्यवहार करे । अधिकांश ठीक से व्यवहार करते हैं (अब), लेकिन यह परीक्षण करना महत्वपूर्ण है। कारण यह है कि आपके द्वारा अमूर्त संचालन के लिए एक ईमानदार जवाब देने के अधिकांश तरीकों का उपयोग आप मेजबान द्वारा प्रदान की गई वस्तु पर भरोसा करना चाहते हैं । इस लेखन के रूप में, ब्राउज़र इस का बहुत अच्छा काम करते हैं, लेकिन 5.1 कल्पना ने इस बात की अनुमति दी है कि मेजबान द्वारा प्रदान की गई वस्तु ईमानदार नहीं हो सकती है। यह big8.6.2 में है , उस खंड की शुरुआत के पास बड़ी तालिका के नीचे कई पैराग्राफ), जहाँ यह कहता है:Array.prototype[[HasProperty]]

होस्ट ऑब्जेक्ट इन आंतरिक तरीकों को किसी भी तरीके से लागू कर सकते हैं जब तक कि अन्यथा निर्दिष्ट न हो; उदाहरण के लिए, एक संभावना यह है कि [[Get]]और [[Put]]एक विशेष मेजबान वस्तु के लिए वास्तव में संपत्ति मूल्यों को प्राप्त करना और संग्रहीत करना है लेकिन [[HasProperty]]हमेशा गलत उत्पन्न करता है

(मैं ES2015 कल्पना में बराबर शब्दाडंबर नहीं मिल सकता है, लेकिन यह अभी भी मामला होने के लिए बाध्य कर रहा है।) फिर, यह के रूप में आम मेजबान प्रदान की [आधुनिक ब्राउज़रों में वस्तुओं सरणी की तरह लिख NodeListउदाहरण के लिए उदाहरणों,] कर संभाल [[HasProperty]]सही ढंग से, लेकिन यह परीक्षण करना महत्वपूर्ण है।)


44
मैं यह भी जोड़ना चाहूंगा कि .forEachकुशलता से तोड़ा नहीं जा सकता। आपको ब्रेक करने के लिए एक अपवाद फेंकना होगा।
पीज्यूसन

82
@ पायस: यदि आप लूप को तोड़ना चाहते हैं, तो आप उपयोग कर सकते हैं some। (मैं भी तोड़ने की अनुमति देना पसंद करूंगा forEach, लेकिन वे, उम, मुझसे नहीं पूछते; ;-))
TJ Crowder

6
@TJCrowder यह सच है, भले ही यह काम के आसपास अधिक दिखता है, क्योंकि यह इसका प्राथमिक उद्देश्य नहीं है।
पीज्यूसन

8
@ user889030: आपको एक की जरूरत है , ,बाद की k=0नहीं ;। याद रखें, प्रोग्रामिंग कई चीजें हैं, जिनमें से एक विस्तार पर ध्यान देना है ... :-)
टीजे क्राउडर

5
@ जिम्ब: यह ऊपर कवर किया गया है (और lengthएक विधि नहीं है)। :-)
टीजे क्राउडर

512

नोट : यह उत्तर निराशाजनक रूप से पुराना है। अधिक आधुनिक दृष्टिकोण के लिए, किसी सरणी पर उपलब्ध विधियों को देखें । ब्याज के तरीके हो सकते हैं:

  • प्रत्येक के लिए
  • नक्शा
  • फिल्टर
  • ज़िप
  • कम करना
  • प्रत्येक
  • कुछ

जावास्क्रिप्ट में एक सरणी को पुनरावृत्त करने का मानक तरीका एक वैनिला- forलूप है:

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

ध्यान दें, हालांकि, यह दृष्टिकोण केवल तभी अच्छा है जब आपके पास एक घने सरणी है, और प्रत्येक सूचकांक में एक तत्व का कब्जा है। यदि सरणी विरल है, तो आप इस दृष्टिकोण के साथ प्रदर्शन समस्याओं में भाग सकते हैं, क्योंकि आप बहुत सारे सूचकांकों पर पुनरावृत्ति करेंगे जो वास्तव में सरणी में मौजूद नहीं हैं। इस मामले में, एक- for .. inलूप एक बेहतर विचार हो सकता है। हालाँकि , आपको यह सुनिश्चित करने के लिए उपयुक्त सुरक्षा उपायों का उपयोग करना चाहिए कि केवल सरणी के वांछित गुण (यानी, सरणी तत्व) पर कार्य किया जाता है, क्योंकि for..in-लूप को विरासत के ब्राउज़रों में भी गणना की जाएगी, या यदि अतिरिक्त गुणों को परिभाषित किया गया है। enumerable

में ECMAScript 5 सरणी प्रोटोटाइप पर एक foreach विधि नहीं होगा, लेकिन यह लिगेसी ब्राउज़र में समर्थित नहीं है। तो इसका लगातार उपयोग करने में सक्षम होने के लिए या तो आपके पास एक ऐसा वातावरण होना चाहिए जो इसका समर्थन करता हो (उदाहरण के लिए, सर्वर साइड जावास्क्रिप्ट के लिए Node.js ), या "Polyfill" का उपयोग करें। इस कार्यक्षमता के लिए पॉलीफिल, हालांकि, तुच्छ है और चूंकि यह कोड को पढ़ना आसान बनाता है, इसलिए इसे शामिल करना एक अच्छा पॉलीफ़िल है।


2
क्यों for(instance in objArray) सही उपयोग नहीं है? यह मेरे लिए और अधिक सरल लगता है, लेकिन मैं आपको इसके बारे में बात करता हूं जो उपयोग के लिए सही तरीका नहीं है?
डांटे

21
आप इनलाइन लंबाई कैशिंग का उपयोग कर सकते हैं: (var i = 0, l = arr.length; मैं <l; i ++)
रॉबर्ट Hoffmann

3
क्या अल्पविराम पहली पंक्ति के इरादे के अंत में है, या यह एक टाइपो (अर्धविराम हो सकता है) है?
मोहम्मद अब्दुल मुजीब

6
@ वर्धा-वेब यह जानबूझकर किया गया है। यह हमें एक एकल- varचिह्न के साथ कई चर घोषित करने में सक्षम बनाता है । यदि हमने अर्धविराम का उपयोग किया elementहोता , तो वैश्विक दायरे में घोषित किया जाता (या, बल्कि, JSHint ने उत्पादन तक पहुंचने से पहले ही हमें चिल्ला दिया होता)।
पैट्रिकअकेस्ट्रास्टैंड

239

यदि आप jQuery लाइब्रेरी का उपयोग कर रहे हैं , तो आप jQuery.each का उपयोग कर सकते हैं :

$.each(yourArray, function(index, value) {
  // do your stuff here
});

संपादित करें:

प्रश्न के अनुसार, उपयोगकर्ता को जावास्क्रिप्ट के बजाय जावास्क्रिप्ट में कोड चाहिए ताकि संपादन हो

var length = yourArray.length;   
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}

2
मैं शायद सबसे अधिक बार इस उत्तर का उपयोग करने जा रहा हूं। यह सवाल का सबसे अच्छा जवाब नहीं है, लेकिन व्यवहार में हम jQuery का उपयोग करने वाले लोगों के लिए सबसे सरल और सबसे अधिक लागू होने जा रहे हैं। मुझे लगता है कि हम सभी को वैनिला का तरीका भी सीखना चाहिए। यह आपकी समझ का विस्तार करने के लिए कभी दर्द नहीं देता।
mopsyd

47
बस इसके लिए: jQuery प्रत्येक बहुत धीमी है तो देशी समाधान। JQuery द्वारा सलाह दी जाती है कि जब भी संभव हो, jQuery के बजाय देशी जावास्क्रिप्ट का उपयोग करें। jsperf.com/browser-diet-jquery-each-vs-for-loop
केविन बॉस

8
जब आप वेनिला का उपयोग कर सकते हैं तो jQuery का उपयोग करने से बचना चाहिए
Noe

2
स्टैण्डर्ड जेएस से चिपके रहें, तीसरी पार्टी के पुस्तकालयों को उत्तर से बाहर रखें जब तक कि मूल भाषा समाधान न हो
स्कैबसेव्यू

116

पीछे की ओर झुकें

मुझे लगता है कि लूप के लिए रिवर्स यहां एक उल्लेख के हकदार हैं:

for (var i = array.length; i--; ) {
     // process array[i]
}

लाभ:

  • आपको एक अस्थायी lenचर घोषित करने या array.lengthप्रत्येक पुनरावृत्ति के खिलाफ तुलना करने की आवश्यकता नहीं है , जिनमें से कोई भी एक मिनट अनुकूलन हो सकता है।
  • उल्टे क्रम में DOM से भाई-बहनों को निकालना आमतौर पर अधिक कुशल होता है । (ब्राउज़र को अपनी आंतरिक सरणियों में तत्वों की शिफ्टिंग कम करने की आवश्यकता है।)
  • यदि आप अनुलग्‍नक के दौरान या अनुक्रमणिका i के बाद सरणी को संशोधित करते हैं (उदाहरण के लिए आप किसी आइटम को निकालते हैं या array[i]उसमें सम्मिलित करते हैं ), तो एक फ़ॉरवर्ड लूप उस आइटम को छोड़ देगा, जिसे मैंने i , या i आइटम पुन: संसाधित किया है सही स्थानांतरित कर दिया। लूप के लिए एक पारंपरिक में, आप i को अगले आइटम को इंगित करने के लिए अपडेट कर सकते हैं जिसे प्रसंस्करण की आवश्यकता है - 1, लेकिन बस पुनरावृत्ति की दिशा को उलट देना अक्सर एक सरल और अधिक सुरुचिपूर्ण समाधान होता है
  • इसी तरह, नेस्टेड डोम तत्वों को संशोधित या हटाते समय , रिवर्स में प्रसंस्करण त्रुटियों को दरकिनार कर सकता है । उदाहरण के लिए, अपने बच्चों को संभालने से पहले एक माता-पिता के नोड के आंतरिक HTML को संशोधित करने पर विचार करें। जब तक बच्चा नोड तक पहुँच जाता है तब तक इसे DOM से अलग कर दिया जाएगा, जब एक नए बनाए गए बच्चे द्वारा प्रतिस्थापित किया जाएगा, जब माता-पिता की आंतरिक HTML लिखी गई होगी।
  • यह उपलब्ध अन्य विकल्पों की तुलना में टाइप करना और पढ़ना कम है। हालांकि यह ES6 के लिए और उससे हार जाता है ।forEach()for ... of

नुकसान:

  • यह वस्तुओं को रिवर्स ऑर्डर में संसाधित करता है। यदि आप परिणामों से एक नई सरणी बना रहे थे, या स्क्रीन पर चीजों को प्रिंट कर रहे थे, तो स्वाभाविक रूप से आउटपुट मूल आदेश के संबंध में उलट हो जाएगा
  • अपने आदेश को बनाए रखने के लिए पहले बच्चे के रूप में डोम में भाई-बहनों को बार-बार सम्मिलित करना कम कुशल होता है । (ब्राउज़र चीजों को सही तरीके से स्थानांतरित करने के लिए रखेगा।) डोम नोड्स को कुशलतापूर्वक और क्रम में बनाने के लिए, बस लूप फॉरवर्ड करें और सामान्य रूप से संलग्न करें (और "दस्तावेज़ टुकड़े" का भी उपयोग करें)।
  • रिवर्स लूप जूनियर डेवलपर्स को भ्रमित कर रहा है। (आप अपने दृष्टिकोण के आधार पर एक लाभ पर विचार कर सकते हैं।)

क्या मुझे हमेशा इसका इस्तेमाल करना चाहिए?

कुछ डेवलपर्स डिफ़ॉल्ट रूप से लूप के लिए रिवर्स का उपयोग करते हैं , जब तक कि लूप फॉरवर्ड करने का एक अच्छा कारण न हो।

हालांकि प्रदर्शन लाभ आमतौर पर नगण्य है, यह चिल्लाती है:

"बस इस सूची में हर आइटम के लिए करते हैं, मैं आदेश के बारे में परवाह नहीं है!"

हालांकि व्यवहार में जो वास्तव में इरादे का एक विश्वसनीय संकेत नहीं है , क्योंकि यह उन अवसरों से अप्रभेद्य है जब आप आदेश की परवाह करते हैं , और वास्तव में रिवर्स में लूप की आवश्यकता होती है। इसलिए वास्तव में एक अन्य निर्माण के लिए "डोंट केयर" इरादे को सही ढंग से व्यक्त करने की आवश्यकता होगी, जो कि वर्तमान में ECMAScript सहित अधिकांश भाषाओं में अनुपलब्ध है, लेकिन जिसे उदाहरण के लिए कहा जा सकता है forEachUnordered()

यदि ऑर्डर मायने नहीं रखता है, और दक्षता एक चिंता है (गेम या एनीमेशन इंजन के अंतरतम लूप में), तो यह आपके गो-टू पैटर्न के रूप में लूप के लिए रिवर्स का उपयोग करने के लिए स्वीकार्य हो सकता है। बस याद रखें कि मौजूदा कोड में लूप के लिए रिवर्स देखने का मतलब यह नहीं है कि ऑर्डर अप्रासंगिक है!

यह forEach का उपयोग करना बेहतर था ()

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

  • यह पढ़ने के लिए स्पष्ट है।
  • यह इंगित करता है कि मैं ब्लॉक के भीतर स्थानांतरित नहीं होने जा रहा हूं (जो हमेशा लंबे forऔर whileछोरों में छिपी एक संभावित आश्चर्य है)।
  • यह आपको क्लोजर के लिए एक नि: शुल्क गुंजाइश देता है।
  • यह बाहरी चर के साथ (और उत्परिवर्तन) स्थानीय चर और आकस्मिक टकराव के रिसाव को कम करता है।

फिर जब आप अपने कोड में लूप के लिए रिवर्स देखते हैं, तो यह एक संकेत है कि यह एक अच्छे कारण के लिए उल्टा है (शायद ऊपर वर्णित कारणों में से एक है)। और लूप के लिए एक पारंपरिक फॉरवर्ड देखने से संकेत मिल सकता है कि शिफ्टिंग हो सकती है।

(यदि इरादे की चर्चा का कोई मतलब नहीं है, तो आप और आपके कोड को प्रोग्रामिंग स्टाइल एंड योर ब्रेन पर क्रॉकफोर्ड के व्याख्यान को देखने से फायदा हो सकता है ।)

यह अब के लिए उपयोग करने के लिए भी बेहतर है..ऑफ!

इस बारे में बहस है कि क्या बेहतर है for..ofया नहीं forEach():

व्यक्तिगत रूप से, मैं पढ़ने में सबसे आसान लग रहा है, जब तक प्रदर्शन या minification एक प्रमुख चिंता का विषय बन गया है का उपयोग करने के लिए करते हैं। इन दिनों तो मैं का उपयोग करना पसंद for..ofके बजाय forEach(), लेकिन मैं हमेशा का उपयोग करेगा mapया filterया findया someजब लागू। (अपने सहयोगियों के लिए, मैं शायद ही कभी उपयोग करता हूं reduce।)


यह कैसे काम करता है?

for (var i = 0; i < array.length; i++) { ... }   // Forwards

for (var i = array.length; i--; )    { ... }   // Reverse

आप देखेंगे कि i--मध्य खंड (जहां हम आमतौर पर एक तुलना देखते हैं) और अंतिम खंड खाली है (जहां हम आमतौर पर देखते हैं i++)। इसका मतलब है कि निरंतरता के लिए शर्त केi-- रूप में भी उपयोग किया जाता है । महत्वपूर्ण रूप से, इसे प्रत्येक पुनरावृत्ति से पहले निष्पादित और जाँच किया जाता है ।

  • यह array.lengthबिना विस्फोट के कैसे शुरू हो सकता है?

    क्योंकि प्रत्येक पुनरावृत्ति से पहलेi-- चलता है , पहले पुनरावृत्ति पर हम वास्तव में उस आइटम तक पहुंच बनाएंगे जिस पर एरे-आउट-ऑफ-बाउंड आइटम के साथ किसी भी मुद्दे से बचा जाता है ।array.length - 1 undefined

  • सूचकांक 0 से पहले पुनरावृति क्यों नहीं रोकती है?

    लूप पुनरावृत्ति को रोक देगा जब स्थिति i--एक गलत मूल्य का मूल्यांकन करती है (जब यह 0 देता है)।

    चाल यह है कि इसके विपरीत --i, अनुगामी i--ऑपरेटर घटता है iलेकिन वेतन वृद्धि से पहले मूल्य प्राप्त करता है । आपका कंसोल यह प्रदर्शित कर सकता है:

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    इसलिए अंतिम पुनरावृत्ति पर, मैं पहले 1 था और i--अभिव्यक्ति इसे 0 में बदल देती है लेकिन वास्तव में 1 (सत्य) की पैदावार होती है , और इसलिए स्थिति गुजरती है। अगले पुनरावृत्ति पर मैं -1 मेंi-- बदल जाता है, लेकिन 0 (फाल्सी) की पैदावार देता है , जिससे लूप के नीचे से तुरंत बाहर निकल जाता है।

    लूप के लिए पारंपरिक फॉरवर्ड में, i++और ++iविनिमेय हैं (जैसा कि डगलस क्रॉकफोर्ड बताते हैं)। हालांकि, लूप के लिए उल्टा, क्योंकि हमारी गिरावट भी हमारी स्थिति की अभिव्यक्ति है, हमें i--अगर हम सूचकांक 0 पर आइटम को संसाधित करना चाहते हैं, तो हमें इसके साथ रहना चाहिए ।


सामान्य ज्ञान

कुछ लोग रिवर्स forलूप में थोड़ा तीर खींचना पसंद करते हैं , और एक पलक के साथ समाप्त होते हैं:

for (var i = array.length; i --> 0 ;) {

मुझे लूप के लिए रिवर्स के फायदे और भयावहता दिखाने के लिए क्रेडिट WYL में जाते हैं।


3
मैं बेंचमार्क जोड़ना भूल गया । मैं यह भी उल्लेख करना भूल गया कि 6502 जैसे 8-बिट प्रोसेसर पर रिवर्स लूपिंग एक महत्वपूर्ण अनुकूलन है, जहां आप वास्तव में मुफ्त में तुलना करते हैं!
joeytwiddle

एक ही जवाब भी बहुत कुछ संक्षेप में दिया जाता है यहाँ (एक अलग प्रश्न पर)।
joeytwiddle

84

कुछ सी -स्टाइल भाषाएं foreachएन्यूमरेशन के माध्यम से लूप का उपयोग करती हैं । जावास्क्रिप्ट में यह for..inलूप संरचना के साथ किया जाता है :

var index,
    value;
for (index in obj) {
    value = obj[index];
}

कुछ पकड़ा गया है। for..inप्रत्येक ऑब्जेक्ट के असंख्य सदस्यों और उसके प्रोटोटाइप पर सदस्यों के माध्यम से लूप करेगा। ऑब्जेक्ट के प्रोटोटाइप के माध्यम से विरासत में मिले मूल्यों को पढ़ने से बचने के लिए, यह जांचें कि क्या संपत्ति ऑब्जेक्ट से संबंधित है:

for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

इसके अतिरिक्त, ECMAScript 5 में एक forEachविधि जोड़ी गई है , Array.prototypeजिसका उपयोग किसी ऐलबैक पर कैलबैक का उपयोग करने के लिए किया जा सकता है (पॉलीफ़िल डॉक्स में है, इसलिए आप इसे अभी भी पुराने ब्राउज़रों के लिए उपयोग कर सकते हैं):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

यह ध्यान रखना महत्वपूर्ण है कि Array.prototype.forEachजब कॉलबैक वापस आए तो वह टूट न जाए falsejQuery और Underscore.jseach लूप प्रदान करने के लिए अपने स्वयं के रूपांतर प्रदान करते हैं जो कि कम-सर्कुलेट किए जा सकते हैं।


3
तो कैसे एक ECMAScript5 के फॉरेस्ट लूप से बाहर निकलता है जैसे हम लूप के लिए एक सामान्य या सी-स्टाइल भाषाओं में पाए जाने वाले फॉरच लूप के लिए करेंगे?
सियारन गलाघेर

5
@CiaranG, जावास्क्रिप्ट में यह उन eachतरीकों को देखने के लिए आम है return falseजो लूप से बाहर निकलने की अनुमति देते हैं , लेकिन इसके साथ forEachकोई विकल्प नहीं है। एक बाहरी झंडे का इस्तेमाल किया जा सकता है (यानी if (flag) return;, लेकिन यह केवल समारोह के बाकी शरीर को क्रियान्वित करने से रोकेगा, forEachफिर भी पूरे संग्रह में इसे जारी रखेगा।
zzzzBov

43

यदि आप किसी सरणी पर लूप करना चाहते हैं, तो मानक तीन-भाग forलूप का उपयोग करें ।

for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}

आप कैशिंग के द्वारा कुछ प्रदर्शन ऑप्टिमाइज़ेशन प्राप्त कर सकते हैं myArray.lengthया इसे पीछे की ओर ले जा सकते हैं।


6
के लिए (var i = 0, लंबाई = myArray.length; मैं <लंबाई; i ++) इसे करना चाहिए
एडसन मदीना

5
@EdsonMedina यह एक नया ग्लोबल वैरिएबल भी बनाएगा, जिसका नाम है length। ;)
joeytwiddle

4
@joeytwiddle हाँ, लेकिन यह इस पद के दायरे से परे है। आप वैसे भी एक वैश्विक चर बनाएंगे।
एडसन मदीना

6
@EdsonMedina मेरी क्षमा याचना, मैं पूरी तरह से गलत था। ,असाइनमेंट के बाद उपयोग करने से एक नया वैश्विक परिचय नहीं होता है , इसलिए आपका सुझाव ठीक है ! मैं इसे एक अलग समस्या के लिए भ्रमित कर रहा था: =एक असाइनमेंट के बाद का उपयोग करके एक नया वैश्विक बनाता है।
joeytwiddle

सावधान चर मैं पाश के लिए स्थानीय नहीं है । जावास्क्रिप्ट में ब्लॉक स्कोप नहीं है। var i, length, arrayItem;इस गलतफहमी से बचने के लिए लूप से पहले घोषित करना बेहतर है ।
जेम्स

35

मुझे पता है कि यह एक पुरानी पोस्ट है, और पहले से ही बहुत सारे शानदार जवाब हैं। थोड़ा और पूर्णता के लिए मुझे लगा कि मैं AngularJS का उपयोग करके एक दूसरे में फेंक दूंगा । बेशक, यह केवल तभी लागू होता है यदि आप कोणीय का उपयोग कर रहे हैं, जाहिर है, फिर भी मैं इसे वैसे भी रखना चाहूंगा।

angular.forEach2 तर्क और एक वैकल्पिक तीसरा तर्क लेता है। पहला तर्क ऑब्जेक्ट (सरणी) को पुनरावृत्त करने के लिए है, दूसरा तर्क इट्रेटर फ़ंक्शन है, और वैकल्पिक तीसरा तर्क ऑब्जेक्ट संदर्भ (मूल रूप से लूप के अंदर 'इस' के रूप में संदर्भित) है।

कोणीय के आगे लूप का उपयोग करने के विभिन्न तरीके हैं। सबसे सरल और शायद सबसे अधिक उपयोग किया जाता है

var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});

एक और तरीका जो एक सरणी से दूसरे में आइटमों की प्रतिलिपि बनाने के लिए उपयोगी है

var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);

हालाँकि, आपको ऐसा करने की ज़रूरत नहीं है, आप बस निम्नलिखित कर सकते हैं और यह पिछले उदाहरण के बराबर है:

angular.forEach(temp, function(item) {
    temp2.push(item);
});

अब angular.forEachवेनिला-स्वाद वाले forलूप में निर्मित के विपरीत फ़ंक्शन का उपयोग करने के पेशेवरों और विपक्ष हैं ।

पेशेवरों

  • आसान पठनीयता
  • आसान लेखन
  • यदि उपलब्ध है, तो angular.forEachES5 forEach लूप का उपयोग करेगा। अब, मैं विपक्ष अनुभाग में कार्यकुशलता प्राप्त करूंगा, क्योंकि फॉरेप लूप लूप्स की तुलना में बहुत धीमे हैं । मैं इसे एक समर्थक के रूप में उल्लेख करता हूं क्योंकि यह सुसंगत और मानकीकृत होना अच्छा है।

निम्नलिखित 2 नेस्टेड छोरों पर विचार करें, जो बिल्कुल वही काम करते हैं। मान लें कि हमारे पास ऑब्जेक्ट्स की 2 सरणियाँ हैं और प्रत्येक ऑब्जेक्ट में परिणामों की एक सरणी होती है, जिनमें से प्रत्येक में एक मान गुण होता है जो एक स्ट्रिंग (या जो भी) होता है। और मान लें कि हमें परिणामों में से प्रत्येक पर पुनरावृति करने की आवश्यकता है और यदि वे समान हैं तो कुछ कार्रवाई करें:

angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});

//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}

दी यह एक बहुत ही सरल काल्पनिक उदाहरण है, लेकिन मैंने दूसरे दृष्टिकोण का उपयोग करते हुए छोरों के लिए ट्रिपल ट्रिपल लिखा है और इसे पढ़ना और उस मामले के लिए लिखना बहुत कठिन था ।

विपक्ष

  • दक्षता। angular.forEach, और forEachउस मामले के लिए देशी , दोनों सामान्य लूप की तुलना में बहुत धीमी हैं for.... लगभग 90% धीमी । तो बड़े डेटा सेट के लिए, देशी forलूप से चिपकना सबसे अच्छा है ।
  • कोई विराम, जारी, या समर्थन वापस न करें। continueवास्तव में " दुर्घटना " द्वारा समर्थित है , ताकि angular.forEachआप साधारण रूप return;से फ़ंक्शन में एक स्टेटमेंट डाल angular.forEach(array, function(item) { if (someConditionIsTrue) return; });सकें , जिसके कारण यह उस पुनरावृत्ति के लिए फ़ंक्शन से बाहर जारी रहेगा। यह इस तथ्य के कारण भी है कि देशी forEachटूटने का समर्थन नहीं करता है या जारी रखता है।

मुझे यकीन है कि विभिन्न अन्य पेशेवरों और विपक्षों के रूप में अच्छी तरह से है, और आप जो भी फिट देखते हैं उसे जोड़ने के लिए स्वतंत्र महसूस करें। मुझे लगता है कि, नीचे की रेखा, यदि आपको दक्षता की आवश्यकता है, तो forअपने लूपिंग की जरूरतों के लिए सिर्फ देशी लूप के साथ रहें । लेकिन, यदि आपके डेटासेट छोटे हैं और पठनीयता और लेखकीयता के बदले कुछ कार्यकुशलता छोड़ना ठीक है, तो हर तरह angular.forEachसे उस बुरे लड़के को फेंक दें ।


34

यदि आपको सरणी खाली करने में कोई आपत्ति नहीं है:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

xका अंतिम मान सम्‍मिलित होगा yऔर इसे सरणी से हटा दिया जाएगा। आप उपयोग भी कर सकते हैं shift()जो पहले आइटम को दे देगा और हटा देगा y


4
यदि आप एक विरल सरणी की तरह होते हैं तो यह काम नहीं करता है [1, 2, undefined, 3]
एम। ग्रेजवेक्यूस्की

2
... या वास्तव में कुछ भी गलत है: [1, 2, 0, 3]या[true, true, false, true]
joeytwield

31

एक पूर्व कार्यान्वयन ( jsFiddle में देखें ):

function forEach(list,callback) {
  var length = list.length;
  for (var n = 0; n < length; n++) {
    callback.call(list[n]);
  }
}

var myArray = ['hello','world'];

forEach(
  myArray,
  function(){
    alert(this); // do something
  }
);

2
इसमें itter, एक अनावश्यक लंबाई गणना कर रहा है। एक आदर्श मामले में, सूची की लंबाई की गणना केवल एक बार की जानी चाहिए।
मिधुन कृष्णा

2
@MIdhunKrishna मैंने अपना उत्तर और jsFiddle अपडेट किया लेकिन ध्यान रखें कि यह उतना आसान नहीं है जितना आप सोचते हैं। इस प्रश्न की
nmoliveira

2
पूर्ण और सही कार्यान्वयन यहां पाया जा सकता है: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
marciowb

29

संभवतः for(i = 0; i < array.length; i++)लूप सबसे अच्छा विकल्प नहीं है। क्यों? यदि आपके पास यह है:

var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";

विधि से कॉल करेंगे array[0]करने के लिए array[2]। पहला, यह पहला संदर्भ चर होगा जो आपके पास भी नहीं है, दूसरा आपके पास सरणी में चर नहीं होगा, और तीसरा यह कोड फ़ोल्डर बना देगा। यहां देखें, यह वही है जो मैं उपयोग करता हूं:

for(var i in array){
    var el = array[i];
    //If you want 'i' to be INT just put parseInt(i)
    //Do something with el
}

और यदि आप चाहते हैं कि यह एक समारोह हो, तो आप यह कर सकते हैं:

function foreach(array, call){
    for(var i in array){
        call(array[i]);
    }
}

यदि आप तोड़ना चाहते हैं, तो थोड़ा और तर्क:

function foreach(array, call){
    for(var i in array){
        if(call(array[i]) == false){
            break;
        }
    }
}

उदाहरण:

foreach(array, function(el){
    if(el != "!"){
        console.log(el);
    } else {
        console.log(el+"!!");
    }
});

यह रिटर्न:

//Hello
//World
//!!!

29

वहाँ के तीन कार्यान्वयन हैं foreachमें jQuery के रूप में इस प्रकार है।

var a = [3,2];

$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3

2
कंसोल लॉग सिर्फ डेमो के लिए है। यह इसे एक चल रहा उदाहरण बनाने के लिए है।
राजेश पॉल

29

ECMAScript 6 के अनुसार:

list = [0, 1, 2, 3]
for (let obj of list) {
    console.log(obj)
}

जहाँ इससे ofजुड़ी विषमताओं से बचा जाता है inऔर यह forकिसी भी अन्य भाषा के पाश की तरह काम करता है , और letबांधता हैi फ़ंक्शन के विपरीत लूप के भीतर है।

{}केवल एक आदेश होने पर ब्रेसिज़ ( ) को छोड़ा जा सकता है (जैसे ऊपर उदाहरण में)।


28

एक आसान समाधान अब अंडरस्कोरजेएस लाइब्रेरी का उपयोग करना होगा । यह कई उपयोगी उपकरण प्रदान कर रहा है, जैसे कि eachऔर स्वचालित रूप से कार्य को मूल निवासी को सौंप देगाforEach यदि उपलब्ध हो तो ।

यह कैसे काम करता है इसका एक कोड उदाहरण है:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

यह सभी देखें


23

for eachदेशी जावास्क्रिप्ट में कोई लूप नहीं है । आप इस कार्यक्षमता को प्राप्त करने के लिए या तो पुस्तकालयों का उपयोग कर सकते हैं (मैं अंडरस्कोर की सलाह देता हूं। ), forलूप में एक साधारण का उपयोग करें ।

for (var instance in objects) {
   ...
}

हालाँकि, ध्यान दें कि एक और भी सरल forलूप का उपयोग करने के कारण हो सकते हैं (देखें स्टैक ओवरफ्लो प्रश्न "सरणी के लिए" का उपयोग क्यों कर रहा है ) इस तरह के एक बुरे विचार के साथ?

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}

22

यह एनओएन-विरल सूची के लिए एक पुनरावृत्ति है जहां सूचकांक 0 से शुरू होता है, जो दस्तावेज़ के साथ काम करते समय विशिष्ट परिदृश्य होता है।

function each( fn, data ) {

    if(typeof fn == 'string')
        eval('fn = function(data, i){' + fn + '}');

    for(var i=0, L=this.length; i < L; i++) 
        fn.call( this[i], data, i );   

    return this;
}

Array.prototype.each = each;  

उपयोग के उदाहरण:

उदाहरण 1

var arr = [];
[1, 2, 3].each( function(a){ a.push( this * this}, arr);
arr = [1, 4, 9]

उदाहरण # 2

each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');

प्रत्येक पी टैग मिलता है class="blue"

उदाहरण # 3

each.call(document.getElementsByTagName('p'), 
    "if( i % 2 == 0) this.className = data;",
    'red'
);

हर दूसरे पी टैग हो जाता है class="red">

उदाहरण # 4

each.call(document.querySelectorAll('p.blue'), 
    function(newClass, i) {
        if( i < 20 )
            this.className = newClass;
    }, 'green'
);

और अंत में पहले 20 ब्लू पी टैग को हरे रंग में बदल दिया जाता है

स्ट्रिंग को फ़ंक्शन के रूप में उपयोग करते समय सावधानी: फ़ंक्शन को आउट-ऑफ-संदर्भ बनाया जाता है और इसका उपयोग केवल उसी स्थान पर किया जाना चाहिए, जहां आप चर स्कोपिंग के बारे में निश्चित हैं। अन्यथा, फ़ंक्शंस पास करने के लिए बेहतर है जहां स्कूपिंग अधिक सहज है।


21

कर रहे हैं के लिए कुछ तरीके नीचे के रूप में, जावास्क्रिप्ट में एक सरणी के माध्यम से लूप करने के लिए:

के लिए - यह सबसे आम है । लूपिंग के लिए कोड का पूरा ब्लॉक

var languages = ["Java", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

जबकि - लूप जबकि एक शर्त के माध्यम से है। यह सबसे तेज लूप लगता है

var text = "";
var i = 0;
while (i < 10) {
    text +=  i + ") something<br>";
    i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

do / जबकि - हालत सही होने पर कोड के एक ब्लॉक के माध्यम से भी लूप करें, कम से कम एक बार चलेगा

var text = ""
var i = 0;

do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);

document.getElementById("example").innerHTML = text;
<p id="example"></p>

कार्यात्मक छोरों - forEach, map, filter, भी reduce(समारोह के माध्यम से वे पाश, पर वे उपयोग किया जाता है कि अगर आप अपने सरणी, आदि के साथ कुछ करने की ज़रूरत है

// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>

सरणियों पर कार्यात्मक प्रोग्रामिंग के बारे में अधिक जानकारी और उदाहरणों के लिए, जावास्क्रिप्ट में ब्लॉग पोस्ट कार्यात्मक प्रोग्रामिंग देखें: मानचित्र, फ़िल्टर और कम करें


छोटा सुधार: forEachयह "कार्यात्मक" लूप नहीं है क्योंकि यह एक नया नहीं लौटाता है Array(वास्तव में यह कुछ भी नहीं लौटाता है), यह सिर्फ पुनरावृत्त करता है।
निकोलसविमिन

19

ECMAScript 5 (जावास्क्रिप्ट पर संस्करण) Arrays के साथ काम करने के लिए:

forEach - सरणी में प्रत्येक आइटम के माध्यम से Iterates और आपको प्रत्येक आइटम के साथ जो कुछ भी आवश्यक है वह करें।

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is #" + (index+1) + " in the musical scale");
});

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

मामले में, कुछ इनबिल्ट सुविधा का उपयोग करके सरणी पर संचालन में अधिक रुचि।

नक्शा - यह कॉलबैक फ़ंक्शन के परिणाम के साथ एक नई सरणी बनाता है। जब आप अपने ऐरे के तत्वों को प्रारूपित करना चाहते हैं तो इस विधि का उपयोग किया जाना अच्छा है।

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});

// Output: ['BOB', 'JOE', 'JEN']

कम करें - जैसा कि नाम कहता है, यह मौजूदा तत्व में दिए गए फ़ंक्शन और पिछले निष्पादन के परिणाम को कॉल करके एकल मान को कम करता है।

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

प्रत्येक - सही या गलत रिटर्न अगर सरणी के सभी तत्व कॉलबैक फ़ंक्शन में परीक्षण पास करते हैं।

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];
ages.every(function(elem) {
  return elem >= 18;
});

// Output: false

फ़िल्टर - उस फ़िल्टर को छोड़कर हर एक के समान, तत्वों के साथ एक सरणी देता है जो दिए गए फ़ंक्शन पर सही लौटता है।

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});

// Output: [2,4,6]

16

अंदर तोड़ने की कोई इनबिल्ट क्षमता नहीं है forEach। निष्पादन को बाधित करने के Array#someलिए नीचे दिए गए उपयोग की तरह:

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

यह काम करता है क्योंकि someकिसी भी कॉलबैक के रूप में जल्द ही सही हो जाता है, सरणी क्रम में निष्पादित किया जाता है, बाकी के निष्पादन को छोटा, सर्कुलेट करता है। मूल उत्तर कुछ के लिए ऐरे प्रोटोटाइप देखें


13

मैं इसे एक रिवर्स लूप की रचना के रूप में जोड़ना चाहता हूं और किसी के लिए उपरोक्त उत्तर जो इस वाक्यविन्यास को भी पसंद करेगा।

var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
    console.log(item);
}

पेशेवरों:

इसके लिए लाभ: आपके पास पहले से ही संदर्भ है जैसे कि बाद में किसी अन्य पंक्ति के साथ घोषित करने की आवश्यकता नहीं होगी। लूपिंग करते समय यह आसान है कि ऑब्जेक्ट एरे को गढ़ा जाए।

विपक्ष:

जब भी संदर्भ गलत होगा तब यह टूट जाएगा - फाल्सी (अपरिभाषित, आदि)। यह एक लाभ के रूप में हालांकि इस्तेमाल किया जा सकता है। हालाँकि, इसे पढ़ना थोड़ा कठिन होगा। और यह भी ब्राउज़र पर निर्भर करता है कि यह मूल के मुकाबले तेजी से काम करने के लिए "नहीं" अनुकूलित हो सकता है।


12

jQuery का उपयोग तरीका $.map:

var data = [1, 2, 3, 4, 5, 6, 7];

var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});

// newData = [2, 4, 6];

1
मुझे लगता है कि आउटपुट होने की अधिक संभावना है [undefined, 2, undefined, 4, undefined, 6, undefined]

10

ECMAScript 6 विनाशकारी और प्रसार ऑपरेटर के साथ छोरों का उपयोग करना

प्रसार ऑपरेटर का विनाश और उपयोग करना नए लोगों के लिए ECMAScript 6 के लिए अधिक मानव-पठनीय / सौंदर्यवादी होने के रूप में काफी उपयोगी साबित हुआ है, हालांकि कुछ जावास्क्रिप्ट दिग्गज इसे गड़बड़ समझ सकते हैं। जूनियर्स या कुछ अन्य लोग इसे उपयोगी पा सकते हैं।

निम्नलिखित उदाहरण for...ofकथन और .forEachविधि का उपयोग करेंगे ।

उदाहरण 6, 7, 8 और जैसे किसी भी कार्यात्मक छोरों के साथ इस्तेमाल किया जा सकता .map, .filter, .reduce, .sort, .every, .some। इन विधियों के बारे में अधिक जानकारी के लिए, Array Object देखें

उदाहरण 1: सामान्य for...ofलूप - यहां कोई चाल नहीं।

let arrSimple = ['a', 'b', 'c'];

for (let letter of arrSimple) {
  console.log(letter);
}

उदाहरण 2: वर्णों को शब्दों को विभाजित करें

let arrFruits = ['apple', 'orange', 'banana'];

for (let [firstLetter, ...restOfTheWord] of arrFruits) {
  // Create a shallow copy using the spread operator
  let [lastLetter] = [...restOfTheWord].reverse();
  console.log(firstLetter, lastLetter, restOfTheWord);
}

उदाहरण 3: के साथ लूपिंग एक keyऔरvalue

// let arrSimple = ['a', 'b', 'c'];

// Instead of keeping an index in `i` as per example `for(let i = 0 ; i<arrSimple.length;i++)`
// this example will use a multi-dimensional array of the following format type:
// `arrWithIndex: [number, string][]`

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Same thing can be achieved using `.map` method
// let arrWithIndex = arrSimple.map((i, idx) => [idx, i]);

// Same thing can be achieved using `Object.entries`
// NOTE: `Object.entries` method doesn't work on Internet Explorer  unless it's polyfilled
// let arrWithIndex = Object.entries(arrSimple);

for (let [key, value] of arrWithIndex) {
  console.log(key, value);
}

उदाहरण 4: इनलाइन गुण वस्तु प्राप्त करें

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];

for (let { name, age: aliasForAge } of arrWithObjects) {
  console.log(name, aliasForAge);
}

उदाहरण 5: आपको जो भी आवश्यक है, उसके गहन वस्तु गुण प्राप्त करें

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

for (let { name, tags: [firstItemFromTags, ...restOfTags] } of arrWithObjectsWithArr) {
  console.log(name, firstItemFromTags, restOfTags);
}

उदाहरण 6: क्या उदाहरण 3 का उपयोग किया जाता है.forEach

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Not to be confused here, `forEachIndex` is the real index
// `mappedIndex` was created by "another user", so you can't really trust it

arrWithIndex.forEach(([mappedIndex, item], forEachIndex) => {
  console.log(forEachIndex, mappedIndex, item);
});

उदाहरण 7: क्या उदाहरण 4 का उपयोग किया जाता है.forEach

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];
// NOTE: Destructuring objects while using shorthand functions
// are required to be surrounded by parentheses
arrWithObjects.forEach( ({ name, age: aliasForAge }) => {
  console.log(name, aliasForAge)
});

उदाहरण 8: क्या उदाहरण 5 का उपयोग किया जाता है.forEach

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

arrWithObjectsWithArr.forEach(({
  name,
  tags: [firstItemFromTags, ...restOfTags]
}) => {
  console.log(name, firstItemFromTags, restOfTags);
});


7

आपके विचार के सबसे नजदीक एक तरीका होगा Array.forEach()जो एक क्लोजर फ़ंक्शन को स्वीकार करता है जिसे एरे के प्रत्येक तत्व के लिए निष्पादित किया जाएगा।

myArray.forEach(
  (item) => {
    // Do something
    console.log(item);
  }
);

एक अन्य व्यवहार्य तरीका होगा Array.map()जो उसी तरह से काम करता है, लेकिन यह उन सभी मूल्यों को भी लेता है जो आप वापस लौटते हैं और उन्हें एक नए सरणी (अनिवार्य रूप से प्रत्येक तत्व को एक नए मैपिंग) में लौटाते हैं, जैसे:

var myArray = [1, 2, 3];
myArray = myArray.map(
  (item) => {
    return item + 1;
  }
);

console.log(myArray); // [2, 3, 4]

1
यह गलत है, mapसरणी के तत्वों को उत्परिवर्तित नहीं करता है, क्योंकि यह एक नया सरणी देता है, उस नए के आइटम के साथ फ़ंक्शन को पुराने सरणी के आइटम पर लागू करने का परिणाम है।
जेसुक्स फ्रैंको

मैंने कभी नहीं कहा कि यह एक नया सरणी नहीं लौटाता है, मैं फ़ंक्शन द्वारा लागू किए गए परिवर्तन का उल्लेख कर रहा था। लेकिन यहाँ मैं इसे उत्तर में बदलूंगा।
एंटे जबलान एडमोविक

फिर से गलत, नक्शा मूल सरणी में सभी वस्तुओं को संशोधित या म्यूट नहीं करता है, मैंने प्रस्तावित किया है और मूल वस्तुओं की एक प्रति के साथ मानचित्र कार्यों पर जोर देते हुए जवाब को संपादित करें , मूल सरणी को सभी पर अछूता छोड़कर
जेसुइस फ्रेंको

7

आप इस तरह से कॉल कर सकते हैं:

forEachआपके द्वारा प्रदान की गई सरणी पर पुनरावृति करेगा और प्रत्येक पुनरावृत्ति के लिए इसके पास elementउस पुनरावृत्ति का मान होगा । यदि आपको इंडेक्स की आवश्यकता है, तो आप iफॉरएच के कॉलबैक फ़ंक्शन में दूसरे पैरामीटर के रूप में वर्तमान इंडेक्स प्राप्त कर सकते हैं ।

Foreach मूल रूप से एक हाई ऑर्डर फंक्शन है, जो एक अन्य फ़ंक्शन को इसके पैरामीटर के रूप में लेता है।

let theArray= [1,3,2];

theArray.forEach((element) => {
  // Use the element of the array
  console.log(element)
}

आउटपुट:

1
3
2

आप इस तरह से एक सरणी पर पुनरावृति कर सकते हैं:

for (let i=0; i<theArray.length; i++) {
  console.log(i); // i will have the value of each index
}

6

यदि आप तीर फ़ंक्शन के साथ ऑब्जेक्ट की एक सरणी के माध्यम से लूप करना चाहते हैं:

let arr = [{name:'john', age:50}, {name:'clark', age:19}, {name:'mohan', age:26}];

arr.forEach((person)=>{
  console.log('I am ' + person.name + ' and I am ' + person.age + ' old');
})


6

लैम्ब्डा सिंटैक्स आमतौर पर इंटरनेट एक्सप्लोरर 10 या उससे कम में काम नहीं करता है।

मैं आमतौर पर उपयोग करता हूं

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});

यदि आप एक jQuery के प्रशंसक हैं और पहले से ही एक jQuery फ़ाइल चल रही है, तो आपको सूचकांक और मान मापदंडों के पदों को उलट देना चाहिए

$("#ul>li").each(function(**index, value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});

5

यदि आपके पास एक विशाल सरणी है तो आपको iteratorsकुछ दक्षता हासिल करने के लिए उपयोग करना चाहिए । Iterators कुछ जावास्क्रिप्ट संग्रह में से एक संपत्ति हैं (जैसे Map, Set, String, Array)। यहां तक ​​कि, अंडर-हुड for..ofका उपयोग करता iteratorहै।

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

आप पुनरावृत्ति nextविधि को कॉल करके वर्तमान आइटम तक पहुँचते हैं । अगली विधि valueवर्तमान आइटम को वापस कर देगी और booleanयह इंगित करने के लिए कि आप संग्रह के अंत तक पहुंच गए हैं। एक सरणी से एक पुनरावृत्ति बनाने का एक उदाहरण निम्नलिखित है।

values()इस तरह से विधि का उपयोग करके अपने नियमित सरणी को पुनरावृत्त में बदलें :

    const myArr = [2,3,4]

let it = myArr.values();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

आप Symbol.iteratorइस तरह का उपयोग करके अपने नियमित सरणी को पुनरावृत्त में बदल सकते हैं :

const myArr = [2,3,4]

let it = myArr[Symbol.iterator]();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

आप अपने नियमित arrayको भी iteratorइस तरह बदल सकते हैं :

let myArr = [8, 10, 12];

function makeIterator(array) {
    var nextIndex = 0;
    
    return {
       next: function() {
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
};

var it = makeIterator(myArr);

console.log(it.next().value);   // {value: 8, done: false}
console.log(it.next().value);   // {value: 10, done: false}
console.log(it.next().value);   // {value: 12, done: false}
console.log(it.next().value);   // {value: undefined, done: true}

नोट :

  • Iterators प्रकृति में संपूर्ण हैं।
  • ऑब्जेक्ट iterableडिफ़ॉल्ट रूप से नहीं हैं । for..inउस स्थिति में उपयोग करें क्योंकि मूल्यों के बजाय यह कुंजी के साथ काम करता है।

आप iteration protocol यहाँ के बारे में अधिक पढ़ सकते हैं ।


5

यदि आप उपयोग करना चाहते हैं forEach(), तो यह दिखेगा -

theArray.forEach ( element => {
    console.log(element);
});

यदि आप उपयोग करना चाहते हैं for(), तो यह दिखेगा -

for(let idx = 0; idx < theArray.length; idx++){
    let element = theArray[idx];
    console.log(element);
}

4

नई अद्यतन सुविधा ECMAScript 6 (ES6) और ECMAScript 2015 के अनुसार, आप निम्न विकल्पों का उपयोग कर सकते हैं:

छोरों के लिए

for(var i = 0; i < 5; i++){
  console.log(i);
}

// Output: 0,1,2,3,4

के लिए ... छोरों में

let obj = {"a":1, "b":2}

for(let k in obj){
  console.log(k)
}

// Output: a,b

Array.forEach ()

let array = [1,2,3,4]

array.forEach((x) => {
  console.log(x);
})

// Output: 1,2,3,4

के लिए ... छोरों की

let array = [1,2,3,4]

for(let x of array){
  console.log(x);
}

// Output: 1,2,3,4

जबकि छोरों

let x = 0

while(x < 5){
  console.log(x)
  x++
}

// Output: 1,2,3,4

करते हैं ... जबकि छोरों

let x = 0

do{
  console.log(x)
  x++
}while(x < 5)

// Output: 1,2,3,4

4

प्रदर्शन

आज (2019-12-18) मैं अपने macOS v10.13.6 (हाई सिएरा) पर क्रोम v 79.0, Safari v13.0.4 और फ़ायरफ़ॉक्स v71.0 (64 बिट) पर परीक्षण करता हूं - अनुकूलन के बारे में निष्कर्ष (और माइक्रो-ऑप्टिमाइज़ेशन जो आमतौर पर इसे कोड के लिए पेश करने के लायक नहीं है क्योंकि लाभ छोटा है, लेकिन कोड जटिलता बढ़ती है)।

  • ऐसा लगता है कि पारंपरिक for i( एए ) सभी ब्राउज़रों पर तेजी से कोड लिखने के लिए एक अच्छा विकल्प है।

  • अन्य समाधान, जैसे for-of( विज्ञापन ), समूह सी में सभी ... आम तौर पर एए की तुलना में 2 - 10 (और अधिक) बार धीमे होते हैं , लेकिन छोटे सरणियों के लिए इसका उपयोग करना ठीक है - वृद्धि कोड स्पष्टता के लिए।

  • में कैश सरणी लंबाई के साथ छोरों n( अब, बी बी, रहो ) कभी कभी तेजी से नहीं कर रहे हैं, कभी कभी। संभवतः संकलक स्वचालित रूप से इस स्थिति का पता लगाते हैं और कैशिंग शुरू करते हैं। कैश्ड और नो-कैश्ड संस्करणों ( Aa, Ba, Bd ) के बीच गति अंतर लगभग ~ 1% है, इसलिए ऐसा लगता है कि परिचय nएक माइक्रो-ऑप्टिमाइज़ेशन है

  • i--समाधान जहां पिछले सरणी तत्व (से पाश शुरू होता है की तरह एसी, ई.पू. शायद यही कारण है की तरीका है -) आगे समाधान की तुलना में आमतौर पर ~ 30% कम होती है सीपीयू मेमोरी कैश काम कर - आगे स्मृति पढ़ने सीपीयू कैशिंग के लिए और अधिक इष्टतम) है। इस तरह के समाधान का उपयोग न करने की सिफारिश की जाती है।

विवरण

परीक्षणों में हम सरणी तत्वों की राशि की गणना करते हैं। मैं छोटे सरणियों (10 तत्वों) और बड़े सरणियों (1M तत्वों) के लिए एक परीक्षण करता हूं और उन्हें तीन समूहों में विभाजित करता हूं:

  • - forपरीक्षण
  • बी - whileपरीक्षण
  • सी - अन्य / वैकल्पिक तरीके

क्रॉस ब्राउज़र परिणाम

सभी परीक्षण किए गए ब्राउज़रों के लिए परिणाम

यहां छवि विवरण दर्ज करेंब्राउज़रों **

10 तत्वों के साथ सरणी

क्रोम के लिए परिणाम। आप यहां अपनी मशीन पर परीक्षण कर सकते हैं ।

यहां छवि विवरण दर्ज करें

1,000,000 तत्वों के साथ सरणी

क्रोम के लिए परिणाम। आप यहां अपनी मशीन पर परीक्षण कर सकते हैं

यहां छवि विवरण दर्ज करें


4

सारांश:

किसी सरणी पर पुनरावृत्ति करते समय, हम अक्सर निम्नलिखित लक्ष्यों में से एक को पूरा करना चाहते हैं:

  1. हम सरणी पर चलना चाहते हैं और एक नया सरणी बनाना चाहते हैं:

    Array.prototype.map

  2. हम सरणी पर पुनरावृति करना चाहते हैं और एक नया सरणी नहीं बनाते हैं:

    Array.prototype.forEach

    for..of पाश

जावास्क्रिप्ट में, इन दोनों लक्ष्यों को पूरा करने के कई तरीके हैं। हालांकि, कुछ दूसरों की तुलना में अधिक सुविधाजनक हैं। नीचे आप जावास्क्रिप्ट में सरणी पुनरावृत्ति को पूरा करने के लिए कुछ आमतौर पर उपयोग किए जाने वाले तरीके (सबसे सुविधाजनक आईएमओ) पा सकते हैं।

नई सरणी बनाना: Map

map()एक ऐसा फंक्शन है, Array.prototypeजिस पर एरे के हर एलिमेंट को ट्रांसफॉर्म किया जा सकता है और फिर एक नया एरे लौटाया जाता है । map()एक कॉलबैक फ़ंक्शन के तर्क के रूप में लेता है और निम्नलिखित तरीके से काम करता है:

let arr = [1, 2, 3, 4, 5];

let newArr = arr.map((element, index, array) => {
  return element * 2;
})

console.log(arr);
console.log(newArr);

कॉलबैक जिसे हम पास कर चुके हैं map() एक तर्क के रूप , हर तत्व के लिए निष्पादित हो जाता है। फिर एक सरणी वापस आ जाती है जिसकी मूल सरणी के समान लंबाई होती है। इसमें नए सरणी तत्व को तर्क के रूप में पारित कॉलबैक फ़ंक्शन द्वारा बदल दिया जाता हैmap()

के बीच स्पष्ट अंतर mapऔर की तरह एक और पाश तंत्र forEachऔर एक for..ofपाश है कि mapरिटर्न एक नई सरणी और पुराने सरणी बरकरार छोड़ देता है (सिवाय यदि आप स्पष्ट रूप से यह हेरफेर की तरह सोचता है के साथ splice)।

इसके अलावा, ध्यान दें कि map फ़ंक्शन का कॉलबैक वर्तमान तर्क की अनुक्रमणिका संख्या को दूसरे तर्क के रूप में प्रदान करता है। इसके अलावा, तीसरा तर्क उस सरणी को प्रदान करता है जिस mapपर कहा जाता था? कभी-कभी ये गुण बहुत उपयोगी हो सकते हैं।

लूप का उपयोग करना forEach

forEachएक फ़ंक्शन है जो Array.prototypeएक तर्क के रूप में कॉलबैक फ़ंक्शन लेता है, जिस पर स्थित है। यह तब सरणी में प्रत्येक तत्व के लिए इस कॉलबैक फ़ंक्शन को निष्पादित करता है। map()फ़ंक्शन के विपरीत , forEach फ़ंक्शन कुछ भी नहीं देता है ( undefined)। उदाहरण के लिए:

let arr = [1, 2, 3, 4, 5];

arr.forEach((element, index, array) => {

  console.log(element * 2);

  if (index === 4) {
    console.log(array)
  }
  // index, and oldArray are provided as 2nd and 3th argument by the callback

})

console.log(arr);

mapफ़ंक्शन की तरह , forEachकॉलबैक वर्तमान तर्क के सूचकांक संख्या को दूसरे तर्क के रूप में प्रदान करता है। साथ ही, तीसरा तर्क उस सरणी को प्रदान करता है जिस forEachपर कहा जाता था?

उपयोग करने वाले तत्वों के माध्यम से लूप करें for..of

for..ofपाश एक सरणी (या किसी अन्य iterable वस्तु) के प्रत्येक तत्व के माध्यम से लूप। यह निम्नलिखित तरीके से काम करता है:

let arr = [1, 2, 3, 4, 5];

for(let element of arr) {
  console.log(element * 2);
}

उपरोक्त उदाहरण में, elementएक सरणी तत्व के लिए खड़ा है और arrवह सरणी है जिसे हम लूप करना चाहते हैं। ध्यान दें कि नामelement मनमाना है, और जब यह लागू होता है, तो हम किसी अन्य नाम जैसे 'एल' या कुछ और घोषणा कर सकते हैं।

for..inलूप के साथ लूप को भ्रमित न करें for..offor..inसरणी के सभी अमूल्य गुणों के माध्यम से for..ofलूप करेगा जबकि लूप केवल सरणी तत्वों के माध्यम से लूप करेगा। उदाहरण के लिए:

let arr = [1, 2, 3, 4, 5];

arr.foo = 'foo';

for(let element of arr) {
  console.log(element);
}

for(let element in arr) {
  console.log(element);
}

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