एसोसिएटिव ऐरे ऑब्जेक्ट पर जावास्क्रिप्ट फॉरेस्ट लूप


181

मेरे प्रत्येक लूप के लिए मेरे जावास्क्रिप्ट साहचर्य सरणी ऑब्जेक्ट पर पुनरावृत्ति क्यों नहीं हो रही है?

// defining an array
var array = [];

// assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";

// expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
    console.log(array[i]);
}

संपादित करें: jQuery each()सहायक हो सकता है: https://api.jquery.com/jQuery.each/


1
आप एक सरणी बनाते हैं, लेकिन फिर इसे मानचित्र के रूप में उपयोग करते हैं। ऐसा लगता है कि आप इसके बजाय एक सादे वस्तु चाहते हैं।
जॉन

4
associative arraysजेएस में ऐसी कोई चीज नहीं है : यह या तो सादा ऐरे या वस्तु है। कुछ भी गैर-संख्यात्मक गुणों को जोड़ने से रोकता है Array, लेकिन इससे ऐसा नहीं होता है associative- विशेष रूप से, lengthसंपत्ति इन गुणों को ऑटो-गिनती नहीं करेगी।
बारिश 7

3
पुन: जेएस में साहचर्य सरणियों जैसी कोई चीज नहीं है। - दूसरे तरीके से शब्द: जावास्क्रिप्ट "नाम का उपयोग करता है" नाम के बजाय "साहचर्य सरणी"। लेकिन इसके पास ".length" संपत्ति नहीं है।
जेसी चिशोल्म

जवाबों:


314

.lengthसंपत्ति केवल संख्यात्मक अनुक्रमित (कुंजी) के साथ गुण ट्रैक करता है। आप चाबी के लिए तार का उपयोग कर रहे हैं।

तुम यह केर सकते हो:

var arr_jq_TabContents = {}; // no need for an array

arr_jq_TabContents["Main"] = jq_TabContents_Main;
arr_jq_TabContents["Guide"] = jq_TabContents_Guide;
arr_jq_TabContents["Articles"] = jq_TabContents_Articles;
arr_jq_TabContents["Forum"] = jq_TabContents_Forum;

for (var key in arr_jq_TabContents) {
    console.log(arr_jq_TabContents[key]);
}

सुरक्षित होने के लिए, यह लूप में एक अच्छा विचार है जैसे कि यह सुनिश्चित करना कि कोई भी गुण विरासत के अप्रत्याशित परिणाम नहीं हैं:

for (var key in arr_jq_TabContents) {
  if (arr_jq_TabContents.hasOwnProperty(key))
    console.log(arr_jq_TabContents[key]);
}

संपादित करें - यह शायद अब एक अच्छा विचार है कि Object.keys()फ़ंक्शन आधुनिक ब्राउज़रों और नोड आदि पर उपलब्ध है। यह फ़ंक्शन किसी सरणी के रूप में किसी ऑब्जेक्ट की "स्वयं" कुंजी देता है:

Object.keys(arr_jq_TabContents).forEach(function(key, index) {
  console.log(this[key]);
}, arr_jq_TabContents);

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


यह क्या var arr_jq_TabContents = {};? मेरा मतलब है {}
सिजमन टोडा

1
@ यह एक खाली वस्तु शाब्दिक है। इसका सिर्फ इतना मतलब है कि चर को एक नई खाली वस्तु के संदर्भ में आरम्भ किया गया है।
नुकीले

@ यदि आपको एक ऐरे उदाहरण की आवश्यकता नहीं है क्योंकि उस कोड में आप इसे जावास्क्रिप्ट ऐरे की तरह उपयोग नहीं कर रहे हैं। जावास्क्रिप्ट में कुछ अन्य भाषाओं की तरह "सहयोगी सरणियाँ" नहीं हैं।
नुकीले

1
असाइन करने []और के बीच अंतर क्या है {}? केवल अलग-अलग प्रोटोटाइप?
सून

8
इसके बजाय hasOwnProperty का उपयोग करना सभी आधुनिक वेब ब्राउज़रों में किसी वस्तु की कुंजी का उपयोग करने के लिए संभव होना चाहिए: Object.keys(arr_jq_TabContents).forEach( function(key) { ... } );
ग्रेगरी बेल

79

यह बहुत सरल तरीका है। फायदा यह है कि आप चाबी भी प्राप्त कर सकते हैं:

for (var key in array) {
    var value = array[key];
    console.log(key, value);
}

ES6 के लिए:

array.forEach(value => {
  console.log(value)
})  

ईएस 6 के लिए: (यदि आप मूल्य, सूचकांक और सरणी चाहते हैं)

array.forEach((value, index, self) => {
  console.log(value, index, self)
})  

12
varलूप्स का उपयोग न करें जो कि स्कूपिंग का सुझाव देते हैं जो मौजूद नहीं है। varलूप के सामने या लूप में उपयोग करें let
छत

2
@ ऐसिंग, क्या आप इस बारे में अधिक बता सकते हैं कि लूप में var का उपयोग क्यों नहीं किया जाता है? मैं C ++ / PHP पृष्ठभूमि से आता हूं और मुझे यह समझ में नहीं आता है। स्कूपिंग लूप में मौजूद है, लेकिन अस्थायी है, इसलिए मुझे यकीन नहीं है कि आपका क्या मतलब है।
डेनिस

6
@ डेनिस अधिकांश भाषाओं में एक forलूप में एक चर घोषणा लूप के शरीर तक सीमित गुंजाइश उत्पन्न करता है for। लेकिन जावास्क्रिप्ट में, आपके द्वारा घोषित एक चर varहमेशा वैश्विक होता है, भले ही आप इसे forलूप में लिखें । यहाँ देखें: davidwalsh.name/for-and-against-let
छत

1
स्मृति प्रति se लीक नहीं है, लेकिन निश्चित रूप से "मेमोरी फैल" है। varजावास्क्रिप्ट में लूप किए जाने के बाद भी मेमोरी में वैरिएबल बनाता है।
अहानजकद

मुझे लगता है कि "var" के उपयोग के बारे में इन टिप्पणियों का बिंदु अब सामान्य रूप से "विशेष रूप से" लूप का उपयोग करना है। ऊपर कारणों को समझाया गया है लेकिन संक्षेप में यह गुंजाइश के कारण है, "var" वैश्विक गुंजाइश बनाता है।
डेजोन

6

पहले से ही कुछ सरल उदाहरण हैं, लेकिन मैंने नोटिस किया है कि आपने अपने प्रश्न को कैसे शब्द दिया है, जो आप शायद पीएचपी पृष्ठभूमि से आते हैं, और आप जावास्क्रिप्ट से उसी तरह काम करने की उम्मीद कर रहे हैं - यह नहीं है। एक PHP arrayएक जावास्क्रिप्ट से बहुत अलग है Array

PHP में, एक साहचर्य सरणी अधिकांश वह कर सकता है जो संख्यात्मक रूप से अनुक्रमित सरणी ( array_*कार्य करता है, आप count()यह कर सकते हैं, आदि) कर सकते हैं ) आप बस एक सरणी बनाते हैं और संख्यात्मक के बजाय स्ट्रिंग-इंडेक्स को असाइन करना शुरू करते हैं।

जावास्क्रिप्ट में, सब कुछ एक वस्तु है (आदिम को छोड़कर: स्ट्रिंग, संख्यात्मक, बूलियन), और सरणियाँ एक निश्चित कार्यान्वयन हैं जो आपको संख्यात्मक सूचकांक देता है। कुछ भी एक सरणी के लिए धक्का दिया अपने प्रभाव होगा length, और (सरणी तरीकों का उपयोग कर अधिक दोहराया जा सकता है map, forEach, reduce, filter, find, आदि) तथापि, क्योंकि कुछ एक ऑब्जेक्ट है, तो आप हमेशा के लिए स्वतंत्र बस असाइन गुण कर रहे हैं, कि कुछ आप के लिए क्या करना है, क्योंकि कोई भी वस्तु। स्क्वायर-ब्रैकेट नोटेशन एक संपत्ति तक पहुंचने का एक और तरीका है, इसलिए आपके मामले में:

array['Main'] = 'Main Page';

वास्तव में इसके बराबर है:

array.Main = 'Main Page';

आपके विवरण से, मेरा अनुमान है कि आप एक 'साहचर्य सरणी' चाहते हैं, लेकिन जावास्क्रिप्ट के लिए, यह एक हैशमैप के रूप में किसी वस्तु का उपयोग करने का एक सरल मामला है। इसके अलावा, मुझे पता है कि यह एक उदाहरण है, लेकिन गैर-सार्थक नामों से बचें जो केवल चर प्रकार (जैसे array) का वर्णन करते हैं , और इसमें जो कुछ भी होना चाहिए, उसके आधार पर नाम है pages। सरल वस्तुओं पुनरावृति करने के लिए कई अच्छे प्रत्यक्ष तरीके नहीं है, तो अक्सर हम सरणियों पहले का उपयोग कर में तो बदल देंगे Objectविधियों ( Object.keysइस मामले में - वहाँ भी है entriesऔर valuesअभी कुछ ब्राउज़रों में जोड़ा जा रहा है), जो हम पाश कर सकते हैं।

// assigning values to corresponding keys
const pages = {
  Main: 'Main page',
  Guide: 'Guide page',
  Articles: 'Articles page',
  Forum: 'Forum board',
};

Object.keys(pages).forEach((page) => console.log(page));

4

arr_jq_TabContents[key] सरणी को 0-इंडेक्स फ़ॉर्म के रूप में देखता है।


4

यहां सामान्य वस्तु प्रकार के रूप में साहचर्य सरणी का उपयोग करने का एक सरल तरीका है:

Object.prototype.forEach = function(cb){
   if(this instanceof Array) return this.forEach(cb);
   let self = this;
   Object.getOwnPropertyNames(this).forEach(
      (k)=>{ cb.call(self, self[k], k); }
   );
};

Object({a:1,b:2,c:3}).forEach((value, key)=>{ 
    console.log(`key/value pair: ${key}/${value}`);
});


4

यदि नोड .js या ब्राउज़र समर्थित है Object.entries(), तो इसका उपयोग Object.keys()( https://stackoverflow.com/a/18804596/225291 ) के विकल्प के रूप में किया जा सकता है ।

const h = {
  a: 1,
  b: 2
};

Object.entries(h).forEach(([key, value]) => console.log(value));
// logs 1, 2

इस उदाहरण में, एक सरणी के विनाशकारी असाइनमेंट का forEachउपयोग करता है ।


1

यह (अनिवार्य रूप से) ज्यादातर मामलों में गलत है:

var array = [];
array["Main"] = "Main page";

यह नाम के साथ सरणी पर एक गैर-तत्व गुण बनाता है Main। हालांकि सरणियाँ ऑब्जेक्ट हैं, आम तौर पर आप उन पर गैर-तत्व गुण नहीं बनाना चाहते हैं।

यदि आप arrayउन नामों से अनुक्रमित करना चाहते हैं , तो आमतौर पर आप एक Mapया एक सादे वस्तु का उपयोग करेंगे , न कि किसी सरणी के।

एक MapES2015 +) के साथ, जिसे मैं mapरचनात्मक कहूंगा

let map = new Map();
map.set("Main", "Main page");

आप तो अपने से iterators का उपयोग कर इसे पुनरावृति values, keysया entriesतरीकों, उदाहरण के लिए:

for (const value of map.values()) {
    // Here, `value` will be `"Main page"`, etc.
}

एक सादे वस्तु का उपयोग करना, जिसे मैं रचनात्मक रूप से कॉल करूंगा obj:

let obj = Object.create(null); // Creates an object with no prototype
obj.Main = "Main page"; // Or: `obj["Main"] = "Main page";`

आप तो का उपयोग कर इसकी सामग्री पुनरावृति होगी Object.keys, Object.valuesया Object.entries, उदाहरण के लिए:

for (const value of Object.values(proches_X)) {
    // Here, `value` will be `"Main page"`, etc.
}

0

var obj = {
  no: ["no", 32],
  nt: ["no", 32],
  nf: ["no", 32, 90]
};

count = -1; // which must be static value
for (i in obj) {
  count++;
  if (obj.hasOwnProperty(i)) {
    console.log(obj[i][count])
  };
};

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

सही विधि, यदि आप रुचि रखते हैं, तो जैसे दबाएं


आप किसी ऐरे को फेंक नहीं रहे हैं, आप उस ऑब्जेक्ट में लूप कर रहे हैं जिसमें एरीज़ है जो किज़ में है। कृपया प्रश्न को पढ़ें और उदाहरण देखें।
पेड्रो जोक्विन

0

तुम यह केर सकते हो

var array = [];

// assigning values to corresponding keys
array[0] = "Main page";
array[1] = "Guide page";
array[2] = "Articles page";
array[3] = "Forum board";


array.forEach(value => {
    console.log(value)
})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.