javascript - जावास्क्रिप्ट में एक सरणी के लिए प्रत्येक के लिए?
arrays loops (19)
जावास्क्रिप्ट का उपयोग कर सरणी में सभी प्रविष्टियों के माध्यम से मैं कैसे लूप कर सकता हूं?
मैंने सोचा कि यह ऐसा कुछ था:
forEach(instance in theArray)
जहां theArray
मेरी सरणी है, लेकिन यह गलत लगता है।
पीछे लूप
मुझे लगता है कि लूप के विपरीत रिवर्स यहां उल्लेखनीय है:
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.length
।array.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 ;) {
मुझे लूप के रिवर्स के लाभ और भय दिखाने के लिए डब्ल्यूवाईएल में क्रेडिट जाते हैं।
सारांश:
एक सरणी पर पुनरावृत्ति करते समय हम अक्सर निम्नलिखित लक्ष्यों में से एक को पूरा करना चाहते हैं:
हम सरणी पर पुन: प्रयास करना चाहते हैं और नई सरणी बनाना चाहते हैं:
Array.prototype.map
हम सरणी पर पुन: प्रयास करना चाहते हैं और एक नई सरणी नहीं बनाते हैं:
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..of
। for..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);
}
यदि आप 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].
}
यदि आप किसी सरणी पर लूप करना चाहते हैं, तो लूप के लिए मानक तीन-भाग का उपयोग करें।
for (var i = 0; i < myArray.length; i++) {
var arrayItem = myArray[i];
}
आप myArray.length
इसे पीछे की ओर कैशिंग या पुनरावृत्त करके कुछ प्रदर्शन अनुकूलन प्राप्त कर सकते हैं ।
ईएस 6 के रूप में:
list = [0, 1, 2, 3]
for (let obj of list) {
console.log(obj)
}
जहां of
से जुड़ी विषमताओं से बचा जाता है in
और यह for
किसी अन्य भाषा के लूप की तरह काम करता है , और फंक्शन के विपरीत लूप के भीतर let
बांधता i
है।
ब्रेसिज़ ( {}
) को छोड़ा जा सकता है जब केवल एक ही आदेश होता है (उदाहरण के लिए ऊपर दिए गए उदाहरण में)।
टी एल; डॉ
- जब तक आप इसे सुरक्षा उपायों के साथ उपयोग न करें तब तक
for-in
उपयोग न करें या कम से कम इस बात से अवगत रहें कि यह आपको क्यों काट सकता है। आपके सबसे अच्छे दांव आमतौर पर होते हैं
लेकिन अन्वेषण करने के लिए बहुत कुछ है, पढ़ें ...
जावास्क्रिप्ट में सरणी और सरणी जैसी वस्तुओं के माध्यम से लूपिंग के लिए शक्तिशाली अर्थशास्त्र है। मैंने जवाब को दो हिस्सों में विभाजित कर दिया है: वास्तविक सरणी के लिए विकल्प, और चीजों के लिए विकल्प जो कि सरणी की तरह हैं , जैसे कि arguments
वस्तु, अन्य पुनरावृत्त वस्तुओं (ES2015 +), DOM संग्रह, आदि।
मैं जल्दी से ध्यान दूंगा कि आप ईएस 55 ईएस 5 को पार करके ईएस 5 इंजन पर भी ईएस2015 विकल्पों का उपयोग कर सकते हैं। अधिक के लिए "ES2015 पारदर्शी" / "ES6 पारदर्शी" के लिए खोजें ...
ठीक है, आइए हमारे विकल्पों को देखें:
वास्तविक Arrays के लिए
आपके पास ECMAScript 5 ("ईएस ECMAScript 5 ") में तीन विकल्प हैं, जो इस समय सबसे व्यापक रूप से समर्थित संस्करण है, और ईसीएमएस्क्रिप्ट ECMAScript 2015 ("ES2015", "ES6") में दो और जोड़े गए हैं:
-
forEach
और संबंधित (forEach
+) के लिए उपयोग करें - लूप के
for
एक सरल का प्रयोग करें - सही ढंग से उपयोग करें
- के लिए उपयोग करें (एक इटरेटर का उपयोग करें) (ES2015 +)
- एक इटरेटर स्पष्ट रूप से उपयोग करें (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]);
}
}
दो चेक नोट करें:
उस वस्तु के पास उस नाम से अपनी संपत्ति है (जिसे वह अपने प्रोटोटाइप से प्राप्त नहीं करता है), और
यह कुंजी अपने सामान्य स्ट्रिंग फॉर्म में बेस -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
वस्तु, आदि। हम उनकी सामग्री के माध्यम से कैसे लूप करते हैं?
सरणी के लिए ऊपर दिए गए विकल्पों में से किसी एक का प्रयोग करें
कम से कम कुछ, और संभावित रूप से सबसे अधिक या यहां तक कि सभी, सरणी दृष्टिकोणों के ऊपर अक्सर ऑब्जेक्ट जैसी वस्तुओं के बराबर अच्छी तरह से लागू होते हैं:
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` });
लूप के
for
एक सरल का प्रयोग करेंजाहिर है, लूप के
for
एक सरल सरणी जैसी वस्तुओं पर लागू होता है।सही ढंग से उपयोग करें
एक ही सुरक्षा के साथ-साथ सरणी के साथ सरणी जैसी वस्तुओं के साथ काम करना चाहिए; उपरोक्त # 1 पर होस्ट-प्रदान की गई वस्तुओं के लिए चेतावनी लागू हो सकती है।
के लिए उपयोग करें (एक इटरेटर का उपयोग करें) (ES2015 +)
ऑब्जेक्ट द्वारा प्रदान किए गए इटरेटर का उपयोग करेगा (अगर कोई है); हमें यह देखना होगा कि यह विभिन्न सरणी जैसी वस्तुओं, विशेष रूप से होस्ट-प्रदान किए गए लोगों के साथ कैसे खेलता है। उदाहरण के लिए,
querySelectorAll
सेquerySelectorAll
लिए विनिर्देश पुनरावृत्ति का समर्थन करने के लिए अद्यतन किया गया था।getElementsByTagName
सेHTMLCollection
लिए spec नहीं था।एक इटरेटर स्पष्ट रूप से उपयोग करें (ES2015 +)
# 4 देखें, हमें देखना होगा कि इटेटरेटर कैसे खेलते हैं।
एक सच्ची सरणी बनाएँ
अन्य बार, आप एक सरणी जैसी वस्तु को एक वास्तविक सरणी में परिवर्तित करना चाहते हैं। ऐसा करना आश्चर्यजनक रूप से आसान है:
सरणी के
slice
विधि का प्रयोग करेंहम सरणी के
slice
विधि का उपयोग कर सकते हैं, जो ऊपर वर्णित अन्य विधियों की तरह है "जानबूझकर सामान्य" और इसलिए सरणी जैसी वस्तुओं के साथ इसका उपयोग किया जा सकता है, जैसे:var trueArray = Array.prototype.slice.call(arrayLikeObject);
तो उदाहरण के लिए, अगर हम एक
NodeList
को एक सच्चे सरणी में परिवर्तित करना चाहते हैं, तो हम यह कर सकते हैं:var divs = Array.prototype.slice.call(document.querySelectorAll("div"));
नीचे होस्ट-प्रदान की गई वस्तुओं के लिए चेतावनी देखें। विशेष रूप से, ध्यान दें कि यह IE8 और इससे पहले में विफल हो जाएगा, जो आपको होस्ट-प्रदत्त ऑब्जेक्ट्स का उपयोग
this
तरह करने की अनुमति नहीं देता है।स्प्रेड सिंटैक्स का उपयोग करें (
...
)इस सुविधा का समर्थन करने वाले जावास्क्रिप्ट इंजनों के साथ ES2015 के स्प्रेड सिंटैक्स का उपयोग करना भी संभव है:
var trueArray = [...iterableObject];
तो उदाहरण के लिए, यदि हम एक
NodeList
को एक सच्चे सरणी में परिवर्तित करना चाहते हैं, तो स्प्रेड सिंटैक्स के साथ यह काफी संक्षिप्त हो जाता है:var divs = [...document.querySelectorAll("div")];
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]]
, लेकिन परीक्षण करना महत्वपूर्ण है।)
Arrays के साथ काम करने के लिए ECMAScript5 (जावास्क्रिप्ट पर संस्करण)।
प्रत्येक के लिए - सरणी में प्रत्येक आइटम के माध्यम से Iterates और प्रत्येक आइटम के साथ जो कुछ भी आपको चाहिए।
['C', 'D', 'E'].forEach(function(element, index) {
console.log(element + " is the #" + (index+1) + " in 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]
उम्मीद है कि यह उपयोगी होगा।
आप इस तरह के लिए कॉल कर सकते हैं:
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
यदि आपको सरणी खाली करने पर कोई फर्क नहीं पड़ता है:
var x;
while(x = y.pop()){
alert(x); //do something
}
x
इसमें अंतिम मान y
होगा और इसे सरणी से हटा दिया जाएगा। आप इसका उपयोग भी कर सकते हैं shift()
जो पहले आइटम को देगा और हटा देगा y
।
यह गैर-स्पैस सूची के लिए एक पुनरावर्तक है जहां सूचकांक 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 ब्लू पी टैग हरे रंग में बदल दिए गए हैं
फ़ंक्शन के रूप में स्ट्रिंग का उपयोग करते समय सावधानी: फ़ंक्शन को संदर्भ के बाहर बनाया गया है और केवल तभी उपयोग किया जाना चाहिए जहां आप चर स्कॉइंग के निश्चित हैं। अन्यथा, उन कार्यों को पारित करने के लिए बेहतर जहां स्कोपिंग अधिक सहज है।
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) प्रस्ताव के हिस्से के रूप में उपयोग करने के अगले तरीके का वर्णन करता है ।
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];
...
}
इसमें तोड़ने की कोई अंतर्निहित क्षमता नहीं है forEach
। निष्पादन को बाधित करने के Array#some
लिए नीचे की तरह उपयोग करें:
[1,2,3].some(function(number) {
return number === 1;
});
यह काम करता है क्योंकि some
जैसे ही कॉलबैक में से कोई भी, सरणी क्रम में निष्पादित, सत्य लौटाता है, शेष के निष्पादन को कम सर्किट करता है। मूल उत्तर some लिए ऐरे प्रोटोटाइप देखेंsome
उपयोग कर 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];
मुझे पता है कि यह एक पुरानी पोस्ट है, और पहले से ही बहुत सारे अच्छे जवाब हैं। थोड़ी अधिक पूर्णता के लिए मैंने सोचा कि मैं AngularJS का उपयोग करके किसी अन्य में फेंक AngularJS । बेशक, यह केवल तभी लागू होता है जब आप कोणीय का उपयोग कर रहे हों, फिर भी, मैं इसे वैसे भी रखना चाहता हूं।
angular.forEach
2 तर्क और एक वैकल्पिक तीसरा तर्क लेता है। पहला तर्क ऑब्जेक्ट (सरणी) को फिर से चालू करने के लिए है, दूसरा तर्क इटरेटर फ़ंक्शन है, और वैकल्पिक तीसरा तर्क ऑब्जेक्ट संदर्भ है (मूल रूप से लूप के अंदर 'यह' के रूप में संदर्भित किया जाता है।
कोणीय के प्रत्येक लूप के लिए उपयोग करने के विभिन्न तरीके हैं। सबसे सरल और शायद सबसे अधिक इस्तेमाल किया जाता है
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.forEach
प्रत्येक लूप के लिए ES5 का उपयोग करेगा। अब, मैं विपक्ष अनुभाग में दक्षता प्राप्त करूंगा, क्योंकि प्रत्येक लूप लूप के मुकाबले बहुत धीमी है। मैं इसे समर्थक के रूप में उल्लेख करता हूं क्योंकि यह सुसंगत और मानकीकृत होना अच्छा है।
निम्नलिखित 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
.... लगभग 9 0% धीमी है । तो बड़े डेटा सेट के लिए, मूलfor
लूप से चिपकने के लिए सबसे अच्छा है । - कोई ब्रेक नहीं, जारी रखें, या समर्थन वापस करें।
continue
वास्तव में " accident " द्वारा समर्थित है , ताकिangular.forEach
आप इसे जारी रखने के लिए फ़ंक्शनreturn;
में एक कथन डालangular.forEach(array, function(item) { if (someConditionIsTrue) return; });
सकें, जिससे इसे पुनरावृत्ति के लिए फ़ंक्शन से बाहर निकलना पड़ेगा। यह इस तथ्य के कारण भी है कि मूलforEach
तोड़ने का समर्थन नहीं करता है या फिर भी जारी रहता है।
मुझे यकीन है कि कई अन्य पेशेवर और विपक्ष भी हैं, और कृपया जो भी आप फिट देखते हैं उसे जोड़ने के लिए स्वतंत्र महसूस करें। मुझे लगता है कि, नीचे की रेखा, यदि आपको दक्षता की आवश्यकता है, तो for
अपनी लूपिंग आवश्यकताओं के लिए केवल देशी पाश के साथ चिपके रहें । लेकिन, यदि आपके डेटासेट छोटे हैं और कुछ दक्षता पठनीयता और उत्तरदायित्व के बदले में छोड़ने के लिए ठीक है, तो हर तरह angular.forEach
से उस बुरे लड़के में फेंक दें ।
यदि आपके पास एक विशाल सरणी है तो आपको 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 बारे में अधिक पढ़ सकते हैं ।
शायद 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
}