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




arrays loops foreach iteration (24)

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

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

JavaScript में एक सरणी को फिर से चलाने का मानक तरीका -लोप के for एक वेनिला 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 -loop को विरासत ब्राउज़र में भी समझा जाएगा, या यदि अतिरिक्त गुणों को enumerable रूप में परिभाषित किया जाता है।

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

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

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

forEach(instance in theArray)

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


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

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

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

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

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

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

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

पेशेवरों:

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

विपक्ष:

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


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

var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
    console.log("Index" + index);
    console.log("Element" + item);
})

तत्व में प्रत्येक इंडेक्स का मान 0 से सरणी की लंबाई तक होगा।

आउटपुट:

let Array = [1,3,2];

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

explaination:

प्रत्येक के लिए प्रोटोटाइप वर्ग में है। आप इसे aArray.prototype.forEach (...) के रूप में भी कॉल कर सकते हैं;

प्रोटोटाइप: https://hackernoon.com/prototypes-in-javascript-5bba2990e04b

आप इस तरह की एक सरणी में भी बदलाव कर सकते हैं:

1    
3    
2

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

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

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

यह भी देखें

  • Array::forEach
  • में for_each...in (MDN) यह समझाया गया है कि for each (variable in object)ECMA-357 (के हिस्से के रूप बहिष्कृत है EAX ) मानक।
  • for...of (एमडीएन) for (variable of object)सद्भाव (ईसीएमएस्क्रिप्ट 6) प्रस्ताव के हिस्से के रूप में उपयोग करने के अगले तरीके का वर्णन करता है ।

उपयोग कर 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];

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

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

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


यह गैर-स्पैस सूची के लिए एक पुनरावर्तक है जहां सूचकांक 0 से शुरू होता है, जो दस्तावेज़ से निपटने के दौरान सामान्य परिदृश्य है .getElementsByTagName या document.querySelectorAll)

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 ब्लू पी टैग हरे रंग में बदल दिए गए हैं

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


निम्नानुसार jQueryforeach में तीन कार्यान्वयन हैं।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

शायद 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
//!!!

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

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

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

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

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


कुछ C स्टाइल भाषाएं गणनाओं के माध्यम से लूप के लिए 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 को forEach विधि के लिए Array.prototype जिसका उपयोग कैलबैक का उपयोग करके सरणी पर गणना करने के लिए किया जा सकता है (पॉलीफिल दस्तावेज़ों में है ताकि आप इसे पुराने ब्राउज़र के लिए अभी भी उपयोग कर सकें):

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

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


ES6 destructuring और प्रसार ऑपरेटर के साथ लूप का उपयोग करना

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

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

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

उदाहरण 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 parenthesis
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);
});


ए के लिए प्रत्येक कार्यान्वयन ( जेएसएफडल में देखें ):

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
  }
);

पीछे लूप

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

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

लाभ:

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

नुकसान:

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

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

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

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

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

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

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

प्रत्येक के लिए उपयोग करना बेहतर है ()

सामान्य रूप से उच्च स्तरीय कोड के लिए जहां स्पष्टता और सुरक्षा अधिक चिंताएं हैं, मैं आपके डिफ़ॉल्ट पैटर्न के रूप में Array::forEach का उपयोग करने की अनुशंसा करता हूं:

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

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

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

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

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

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

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

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

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

  • इंडेक्स 0 से पहले यह फिर से क्यों नहीं रोकता है?

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

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

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

    [5, 5, 4]

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

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

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

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

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

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


सारांश:

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

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

    Array.prototype.map

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

    Array.prototype.forEach

    for..of पाश

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

नई सरणी बनाना: 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()फ़ंक्शन के विपरीत फ़ंक्शन प्रत्येक फ़ंक्शन कुछ भी नहीं देता है ( 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);
}


टी एल; डॉ

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

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

लेकिन अन्वेषण करने के लिए बहुत कुछ है, पढ़ें ...

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

मैं जल्दी से ध्यान दूंगा कि आप ईएस 55 ईएस 5 को पार करके ईएस 5 इंजन पर भी ईएस2015 विकल्पों का उपयोग कर सकते हैं। अधिक के लिए "ES2015 पारदर्शी" / "ES6 पारदर्शी" के लिए खोजें ...

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

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

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

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

विवरण:

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

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

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

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

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

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

यदि आप प्रत्येक सरणी प्रविष्टि के लिए फ़ंक्शन कॉल करने की रनटाइम लागत के बारे में चिंतित हैं, तो मत बनें; blog.niftysnippets.org/2012/02/foreach-and-runtime-cost.html

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

  • every (कॉलबैक पहली बार false बोलता है या कुछ false बोलता है)
  • some (कॉलबैक पहली बार लौटता true या कुछ true कहता है)
  • filter (तत्वों सहित एक नई सरणी बनाता है जहां फ़िल्टर फ़ंक्शन true लौटाता true और जहां इसे false लौटाता false )
  • map (कॉलबैक द्वारा लौटाए गए मानों से एक नई सरणी बनाता है)
  • reduce (कॉलबैक को बार-बार कॉल करके एक मूल्य बनाता है, पिछले मानों में गुजर रहा है; विवरण के लिए spec देखें; एक सरणी की सामग्री को सूचीबद्ध करने के लिए उपयोगी और कई अन्य चीजें)
  • reduce ( 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); // 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 => {
        alert("Index is: " + index);
    });
}

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

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

आप लोग आपको for-in का उपयोग करने के लिए कहेंगे, लेकिन यह नहीं है कि इसमें क्या हैकिसी ऑब्जेक्ट की संख्यात्मक गुणों के माध्यम से लूप के लिए, सरणी की अनुक्रमणिका नहीं। ऑर्डर की गारंटी नहीं है , यहां तक ​​कि ES2015 (ES6) में भी नहीं। ES2015 गुणों को ऑब्जेक्ट करने के लिए ऑर्डर परिभाषित करता है ( [[OwnPropertyKeys]] , [[Enumerate]] , और चीजें जो Object.getOwnPropertyKeys जैसे Object.getOwnPropertyKeys उपयोग Object.getOwnPropertyKeys ), लेकिन यह परिभाषित नहीं करता है कि 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 are explained
        /^0$|^[1-9]\d*$/.test(key) &&    // and then hidden
        key <= 4294967294                // away below
        ) {
        console.log(a[key]);
    }
}

दो चेक नोट करें:

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

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

यह अधिकांश सरणी पर प्रति लूप पुनरावृत्ति का एक छोटा सा हिस्सा है, लेकिन यदि आपके पास एक स्पैस सरणी है, तो यह लूप के लिए एक और अधिक प्रभावी तरीका हो सकता है क्योंकि यह केवल उन प्रविष्टियों के लिए लूप करता है जो वास्तव में मौजूद हैं। उदाहरण के लिए, उपर्युक्त सरणी के लिए, हम कुल तीन बार लूप करते हैं (कुंजी "0" , "10" , और "10000" - याद रखें, वे तार हैं), 10,001 बार नहीं।

अब, आप हर बार लिखना नहीं चाहेंगे, इसलिए आप इसे अपने टूलकिट में डाल सकते हैं:

function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) && /^0$|^[1-9]\d*$/.test(prop) && prop <= 4294967294; // 2^32 - 2
}

और फिर हम इसका इस्तेमाल इस तरह करेंगे:

for (key in a) {
    if (arrayHasOwnIndex(a, key)) {
        console.log(a[key]);
    }
}

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

for (key in a) {
    // "Good enough" for most cases
    if (String(parseInt(key, 10)) === key && a.hasOwnProperty(key)) {
        console.log(a[key]);
    }
}

4. के लिए उपयोग करें (एक इटरेटर का उपयोग करें) (ES2015 +)

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

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

आउटपुट:

a
b
c

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

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

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

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

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

value का अर्थ इटरेटर के आधार पर भिन्न होता है; सरणी समर्थन (कम से कम) तीन कार्यों जो iterators वापस:

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

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

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

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

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

  1. forEach और संबंधित ( forEach +) के लिए उपयोग करें

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

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

    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. सही ढंग से उपयोग करें

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

  4. के लिए उपयोग करें (एक इटरेटर का उपयोग करें) (ES2015 +)

    ऑब्जेक्ट द्वारा प्रदान किए गए इटरेटर का उपयोग करेगा (अगर कोई है); हमें यह देखना होगा कि यह विभिन्न सरणी जैसी वस्तुओं, विशेष रूप से होस्ट-प्रदान किए गए लोगों के साथ कैसे खेलता है। उदाहरण के लिए, querySelectorAll से querySelectorAll लिए विनिर्देश पुनरावृत्ति का समर्थन करने के लिए अद्यतन किया गया था। getElementsByTagName से HTMLCollection लिए spec नहीं था।

  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 के स्प्रेड सिंटैक्स का उपयोग करना भी संभव है:

    var trueArray = [...iterableObject];
    

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

    var divs = [...document.querySelectorAll("div")];
    
  3. Array.from (spec) प्रयोग करें (MDN)

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

    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 फ़ंक्शंस का उपयोग करते हैं), तो आपको यह सुनिश्चित करने के लिए अपने लक्षित वातावरण में परीक्षण करना होगा कि मेजबान द्वारा प्रदान किया गया हो वस्तु ठीक से व्यवहार करती है। अधिकांश ठीक से व्यवहार करते हैं (अब), लेकिन परीक्षण करना महत्वपूर्ण है। इसका कारण यह है कि अधिकांश Array.prototype विधियों का उपयोग आप होस्ट-प्रदत्त ऑब्जेक्ट पर भरोसा करना चाहते हैं जो सार [[HasProperty]] ऑपरेशन के लिए ईमानदार उत्तर देते हैं। इस लेखन के अनुसार, ब्राउज़र इस का बहुत अच्छा काम करते हैं, लेकिन 5.1 spec ने संभावना के लिए अनुमति दी है कि होस्ट-प्रदान की गई वस्तु ईमानदार नहीं हो सकती है। यह §8.6.2 , उस खंड की शुरुआत के पास बड़ी तालिका के नीचे कई पैराग्राफ), जहां यह कहता है:

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

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


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

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

आप myArray.lengthइसे पीछे की ओर कैशिंग या पुनरावृत्त करके कुछ प्रदर्शन अनुकूलन प्राप्त कर सकते हैं ।


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

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

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>

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

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>

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


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

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

एक अन्य व्यवहार्य तरीका का उपयोग करना होगा Array.map()जो एक ही तरीके से काम करता है लेकिन mutatesप्रत्येक तत्व भी इसे वापस देता है:

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

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

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

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

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

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

यदि आपके पास एक विशाल सरणी है तो आपको 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से iteratorsइस तरह से बदल सकते हैं :

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 here बारे में अधिक पढ़ सकते हैं ।


मेरे पास सरणी से हटाने के लिए एक और अच्छा समाधान है:

var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

filter







javascript arrays loops foreach iteration