जावास्क्रिप्ट ऑब्जेक्ट पर पुनरावृति कैसे करें?


422

मेरे पास जावास्क्रिप्ट में एक वस्तु है:

{
    abc: '...',
    bca: '...',
    zzz: '...',
    xxx: '...',
    ccc: '...',
    // ...
}

मैं forइसके गुणों को प्राप्त करने के लिए एक लूप का उपयोग करना चाहता हूं । और मैं इसे भागों में पुनरावृत्त करना चाहता हूं (एक बार में सभी ऑब्जेक्ट गुण नहीं)।

एक साधारण सरणी के साथ मैं इसे एक मानक forलूप के साथ कर सकता हूं :

for (i = 0; i < 100; i++) { ... } // first part
for (i = 100; i < 300; i++) { ... } // second
for (i = 300; i < arr.length; i++) { ... } // last

लेकिन वस्तुओं के साथ यह कैसे करना है?


22
ध्यान रखें कि ऑब्जेक्ट गुण क्रम में संग्रहीत नहीं हैं। जब आप किसी वस्तु पर पुनरावृति करते हैं तो उस क्रम की कोई गारंटी नहीं है जिसमें वे दिखाई देंगे।
जेम्स एलार्डिस

जवाबों:


850

अधिकांश वस्तुओं के लिए, उपयोग करें for .. in:

for (let key in yourobject) {
  console.log(key, yourobject[key]);
}

ES6 के साथ, यदि आपको एक साथ कुंजी और मान दोनों की आवश्यकता है, तो करें

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

विरासत में मिली प्रॉपर्टीज से बचने के लिए, hasOwnProperty के साथ जांच करें :

for (let key in yourobject) {
   if (yourobject.hasOwnProperty(key)) {
      console.log(key, yourobject[key]);
   }
}

hasOwnPropertyयदि आप एक साधारण वस्तु का उपयोग कर रहे हैं (उदाहरण के लिए आप खुद के साथ किए गए हैं {}) तो आपको यह जांचने की आवश्यकता नहीं है कि आप क्या कर रहे हैं ।

यह एमडीएन प्रलेखन वस्तुओं और उनकी संपत्तियों से निपटने के बारे में अधिक सामान्यतः बताता है।

यदि आप इसे "विखंडू" में करना चाहते हैं, तो सबसे अच्छा है कि आप किसी ऐरे में कुंजियाँ निकालें। जैसा कि आदेश की गारंटी नहीं है, यह उचित तरीका है। आधुनिक ब्राउज़रों में, आप उपयोग कर सकते हैं

let keys = Object.keys(yourobject);

अधिक संगत होने के लिए, आप इसे बेहतर करेंगे:

 let keys = [];
 for (let key in yourobject) {      
     if (yourobject.hasOwnProperty(key)) keys.push(key);
 }

फिर आप सूचकांक द्वारा अपने गुणों पर पुनरावृति कर सकते हैं yourobject[keys[i]]:

for (let i=300; i < keys.length && i < 600; i++) { 
   console.log(keys[i], yourobject[keys[i]]);
}

3
ओपी चंक्स में यह प्रदर्शन करना चाहता है, एक ही लूप में सभी चाबियाँ नहीं।
पावेल १el

हाँ। एक लूप में पूरी वस्तु नहीं।
नखत

2
@Cerbrus ओपी पहले से ही जानता है कि कैसे भागों में एक सरणी को पुनरावृत्त करना है। keysदिए गए कोड से उपयोग करना पर्याप्त होना चाहिए।
योशी

2
@Cerbrus टिप्पणी करने से पहले पढ़ें! "अधिक संगत होने के लिए, आप इसे बेहतर करेंगे, यह स्पष्ट नहीं है " ?
डेनिस सेगुरेट

2
@ am05mhz जैसा कि मैंने कहा, यह अधिकांश वस्तुओं के साथ बेकार है। लेकिन सभी के लिए नहीं। इसे आज़माएं: jsbin.com/hirivubuta/1/edit?js,console,output
Denys Séguret

61

यहाँ आधुनिक ब्राउज़रों के लिए एक और पुनरावृत्ति समाधान है:

Object.keys(obj)
  .filter((k, i) => i >= 100 && i < 300)
  .forEach(k => console.log(obj[k]));

या फिल्टर फ़ंक्शन के बिना:

Object.keys(obj).forEach((k, i) => {
    if (i >= 100 && i < 300) {
        console.log(obj[k]);
    }
});

हालाँकि, आपको इस बात पर विचार करना चाहिए कि जावास्क्रिप्ट ऑब्जेक्ट में गुण क्रमबद्ध नहीं हैं, अर्थात इसका कोई क्रम नहीं है।


अगर मैं लूप को तोड़ दूंगा, तो यह अगली बार ऑब्जेक्ट की शुरुआत से शुरू होगा, यह सही तरीका नहीं है।
नकुहता

21

Object.entriesआप का उपयोग कुछ इस तरह से करते हैं।

 // array like object with random key ordering
 const anObj = { 100: 'a', 2: 'b', 7: 'c' };
 console.log(Object.entries(anObj)); // [ ['2', 'b'],['7', 'c'],['100', 'a'] ]

Object.entries () विधि किसी दिए गए ऑब्जेक्ट की अपनी असंख्य संपत्ति [कुंजी, मान] की एक सरणी देता है

तो आप ऑब्जेक्ट पर पुनरावृति कर सकते हैं keyऔर valueप्रत्येक वस्तु के लिए और ऐसा कुछ प्राप्त कर सकते हैं।

const anObj = { 100: 'a', 2: 'b', 7: 'c' };
Object.entries(anObj).map(obj => {
   const key   = obj[0];
   const value = obj[1];

   // do whatever you want with those values.
});

या इस तरह

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});

एक संदर्भ के लिए ऑब्जेक्ट एंट्रीज़ के लिए MDN डॉक्स पर एक नज़र है


17

नए ES6 / ES2015 सुविधाओं के साथ, आपको हैश पर पुनरावृति करने के लिए किसी ऑब्जेक्ट का उपयोग करने की आवश्यकता नहीं है। आप एक मानचित्र का उपयोग कर सकते हैं । जावास्क्रिप्ट मैप्स इंसर्शन क्रम में चाबियां रखते हैं, जिसका अर्थ है कि आप उन पर हैरोवैनपार्टी की जांच किए बिना उस पर पुनरावृति कर सकते हैं, जो हमेशा एक हैक था।

एक नक्शे पर Iterate:

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

for (var key of myMap.keys()) {
  console.log(key);
}
// Will show 2 logs; first with "0" and second with "1"

for (var value of myMap.values()) {
  console.log(value);
}
// Will show 2 logs; first with "zero" and second with "one"

for (var [key, value] of myMap.entries()) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

या forEach का उपयोग करें:

myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
}, myMap)
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

1
फॉरएच को सबसे ज्यादा पसंद किया जाता है
पुंगगि

14

यदि आपको पुनरावृत्ति करते समय कुंजी और मान चाहिए , तो आप Object.entries वाले लूप के लिए ... का उपयोग कर सकते हैं ।

const myObj = {a: 1, b: 2}

for (let [key, value] of Object.entries(myObj)) {
    console.log(`key=${key} value=${value}`)
}

// output: 
// key=a value=1
// key=b value=2

7

ऐसा करने का एकमात्र विश्वसनीय तरीका अपने ऑब्जेक्ट डेटा को 2 सरणियों, कुंजियों में से एक और डेटा के लिए सहेजना होगा:

var keys = [];
var data = [];
for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        keys.push(key);
        data.push(obj[key]); // Not necessary, but cleaner, in my opinion. See the example below.
    }
}

इसके बाद आप आम तौर पर जैसे ऐरीज़ पर पुनरावृति कर सकते हैं:

for(var i = 0; i < 100; i++){
    console.log(keys[i], data[i]);
    //or
    console.log(keys[i], obj[keys[i]]); // harder to read, I think.
}
for(var i = 100; i < 300; i++){
    console.log(keys[i], data[i]);
}

मैं उपयोग नहीं कर रहा हूं Object.keys(obj), क्योंकि वह IE 9+ है।


3

-> यदि हम जावास्क्रिप्ट ऑब्जेक्ट का उपयोग करने और ऑब्जेक्ट्स की सरणी की कुंजी खोजने के लिए पुनरावृति करते हैं

Object.keys(Array).forEach(key => {

 console.log('key',key)

})

1

यदि आप एक बार में for inलूप का उपयोग कर सकते हैं, तो आप पूरे ऑब्जेक्ट को पुनरावृत्त करना चाहते हैं :

for (var i in obj) {
  ...
}

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

उनमें से सबसे पहले पढ़ी गई संपत्तियों को "हटाने" के लिए है:

var i = 0;
for (var key in obj) {
    console.log(obj[key]);
    delete obj[key];
    if ( ++i > 300) break;
}

एक और उपाय जो मैं सोच सकता हूं वह यह है कि वस्तु के बजाय ऐरे का उपयोग करें:

var obj = [['key1', 'value1'], ['key2', 'value2']];

फिर, मानक forलूप काम करेगा।


1

मैं आखिरकार वस्तुओं, स्ट्रिंग्स, एर्रेज़, टाइपेडरेज़, मैप्स, सेट्स, (किसी भी Iterables) को एकीकृत करने के लिए एकीकृत इंटरफ़ेस फ़ंक्शन के साथ एक उपयोगी उपयोगिता फ़ंक्शन के साथ आया।

const iterate = require('@a-z/iterate-it');
const obj = { a: 1, b: 2, c: 3 };

iterate(obj, (value, key) => console.log(key, value)); 
// a 1
// b 2
// c 3

https://github.com/alrik/iterate-javascript


1

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

var  users  =   {
    'fred':     { 
        'user':   'fred',
            'age':  40 
    },
    'pebbles':  { 
        'user':   'pebbles',
         'age':  1 
    }
}; 
_.mapValues(users,  function(o)  { 
    return  o.age; 
});
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
// The `_.property` iteratee shorthand.
console.log(_.mapValues(users,  'age')); // returns age property & value 
console.log(_.mapValues(users,  'user')); // returns user property & value 
console.log(_.mapValues(users)); // returns all objects 
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-compat/3.10.2/lodash.js"></script>


1

ऑब्जेक्ट पुनरावृत्ति के लिए हम आमतौर पर एक for..inलूप का उपयोग करते हैं । यह संरचना सभी प्रगणनीय गुणों के माध्यम से लूप करेगी , जिसमें प्रोटोटाइप विरासत के माध्यम से विरासत में शामिल हैं। उदाहरण के लिए:

let obj = {
  prop1: '1',
  prop2: '2'
}

for(let el in obj) {
  console.log(el);
  console.log(obj[el]);
}

हालांकि, for..inसभी गणना करने योग्य तत्वों पर लूप होगा और यह हमें विखंडू में पुनरावृत्ति को विभाजित करने में सक्षम नहीं करेगा। इसे प्राप्त करने के लिए हम Object.keys()किसी प्रकार से किसी ऑब्जेक्ट की सभी कुंजियों को पुनः प्राप्त करने के लिए फंक्शन में बिल्ट इन फंक्शन का उपयोग कर सकते हैं । हम फिर लूप के लिए कई में पुनरावृत्ति को विभाजित कर सकते हैं और कुंजी सरणी का उपयोग करके गुणों तक पहुंच सकते हैं। उदाहरण के लिए:

let obj = {
  prop1: '1',
  prop2: '2',
  prop3: '3',
  prop4: '4',
};

const keys = Object.keys(obj);
console.log(keys);


for (let i = 0; i < 2; i++) {
  console.log(obj[keys[i]]);
}


for (let i = 2; i < 4; i++) {
  console.log(obj[keys[i]]);
}


0
var Dictionary = {
  If: {
    you: {
      can: '',
      make: ''
    },
    sense: ''
  },
  of: {
    the: {
      sentence: {
        it: '',
        worked: ''
      }
    }
  }
};

function Iterate(obj) {
  for (prop in obj) {
    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
      console.log(prop + ': ' + obj[prop]);
      Iterate(obj[prop]);
    }
  }
}
Iterate(Dictionary);

1
दरअसल नहीं। इसका तात्पर्य है कि Objectएस क्रम में हैं। वे नहीं हैं। If you can make sense of the sentence it workedकेवल कार्यान्वयन विवरण के कारण काम करता है। यह काम करने की गारंटी नहीं है। इसके अलावा आप अपने कार्यों और चर शीर्षक नहीं होना चाहिए। यह classतों के लिए है ।
फ्लोरियन वेंडेलबोर्न

0

वास्तव में एक PITA यह मानक जावास्क्रिप्ट का हिस्सा नहीं है।

/**
 * Iterates the keys and values of an object.  Object.keys is used to extract the keys.
 * @param object The object to iterate
 * @param fn (value,key)=>{}
 */
function objectForEach(object, fn) {
    Object.keys(object).forEach(key => {
        fn(object[key],key, object)
    })
}

नोट: मैंने कॉलबैक मापदंडों को स्विच किया (मान, कुंजी) और एपीआई को लगातार दूसरे एपीआई बनाने के लिए एक तीसरी वस्तु को जोड़ा।

इसे इस तरह इस्तेमाल करें

const o = {a:1, b:true};
objectForEach(o, (value, key, obj)=>{
    // do something
});

1
पहले वाक्य में केवल आपके कथन के लिए upvoted। भले ही यह बेहतर होगा यदि मूल्य पहले पैरामीटर, सूचकांक या कुंजी दूसरा पैरामीटर, और ऑब्जेक्ट तीसरा पैरामीटर है, इसे सरणी forEach () की तरह अधिक बनाने के लिए। मैं हालांकि लॉश की सिफारिश करना चाहूंगा।
CONTRACT SAYS आई एम आर राइट

मैं (मूल्य, कुंजी) आदेश के विचार को पसंद करता हूं। ऐसा ही एक पुस्तकालय जैसे Vue भी करता है। क्योंकि वस्तु संदर्भ है, लेकिन उसे लगता है कि यह पहले पैरामीटर के रूप में है। कार्यात्मक प्रोग्रामिंग के लिए यह बहुत मानक है।
स्टीवन स्पंगिन

मैं यहाँ सहमत हूँ, क्या यह ईसीएमए -262 के लिए नहीं था, एक वस्तु को परिभाषित करने वाली वस्तु के रूप में एक forEach (), नक्शा (), घटाना (), फ़िल्टर (), जो सभी कॉलबैक प्राप्त करता है जो आदेश प्राप्त करता है [मूल्य, सूचकांक, सरणी] । जेएस में एक वस्तु को सिर्फ एक अन्य संग्रह के रूप में समझा जा सकता है; और फिर ये विधियाँ उनके मान [कुंजी, इंडेक्स, संदर्भ] के मापदंडों में एकीकृत हो जाती हैं (यह वही है जो लॉश और अंडरस्कोर कर रहा है)। मेरी राय में, यह "एकीकृत संग्रह" प्रोटोकॉल सिर्फ मजबूत है। इसके अलावा, ऑब्जेक्ट संदर्भ नहीं है: आप thisकॉलबैक के लिए जो कुछ भी पसंद करते हैं उसे सेट कर सकते हैं , क्योंकि कॉलबैक का अपना संदर्भ है।
अनुबंध SAYS मैं

शायद मुझे इसके बजाय काम रिसीवर का उपयोग करना चाहिए था। वैसे भी अभी भी एक PITA; मैं किसी भी क्रम में मापदंडों का स्वागत करूंगा।
स्टीवन स्पंगिन

ओह, मैं देख रहा हूं कि हम एक दूसरे को गलत समझ सकते हैं। मैं हमेशा कॉलबैक मापदंडों और उनके आदेश के बारे में टिप्पणी कर रहा था, वास्तविक objectForEachकार्य के बारे में नहीं । क्षमा करें यदि वह भ्रमित था।
CONTRACT SAYS आई एम आर राइट

0

हाँ। आप लूप का उपयोग करके किसी ऑब्जेक्ट के माध्यम से लूप कर सकते हैं। यहाँ एक उदाहरण है

var myObj = {
    abc: 'ABC',
    bca: 'BCA',
    zzz: 'ZZZ',
    xxx: 'XXX',
    ccc: 'CCC',
}

var k = Object.keys (myObj);
for (var i = 0; i < k.length; i++) {
    console.log (k[i] + ": " + myObj[k[i]]);
}

नोट: ऊपर उल्लिखित उदाहरण केवल IE9 + में काम करेगा। Objec.keys ब्राउज़र समर्थन देखें यहाँ


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