javascript - वस्तु गुणों के माध्यम से Iterate




loops object (16)

For..in लूप क्या करता है यह है कि यह एक नया चर (var कुछ वैरिएबल) बनाता है और फिर दिए गए ऑब्जेक्ट की प्रत्येक प्रॉपर्टी को इस नए चर (कुछ उपलब्ध) में एक-एक करके स्टोर करता है। इसलिए यदि आप ब्लॉक {} का उपयोग करते हैं, तो आप फिर से सक्रिय कर सकते हैं। निम्नलिखित उदाहरण पर विचार करें।

var obj = {
     name:'raman',
     hobby:'coding',
     planet:'earth'
     };

for(var someVariable in obj) {
  //do nothing..
}

console.log(someVariable); // outputs planet
var obj = {
    name: "Simon",
    age: "20",
    clothing: {
        style: "simple",
        hipster: false
    }
}

for(var propt in obj){
    alert(propt + ': ' + obj[propt]);
}

परिवर्तनीय propt ऑब्जेक्ट के गुणों का प्रतिनिधित्व कैसे करता है? यह एक अंतर्निहित विधि या संपत्ति नहीं है। तो यह वस्तु में हर संपत्ति के साथ क्यों आता है?


jquery आपको यह करने की अनुमति देता है:

$.each( obj, function( key, value ) {
  alert( key + ": " + value );
});

आप मूल रूप से वस्तु में प्रत्येक संपत्ति के माध्यम से लूप करना चाहते हैं।

JSFiddle

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

आप लोडाश का उपयोग कर सकते हैं। दस्तावेज़ीकरण

var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
    ...
});

ईएस के आगामी संस्करणों में, आप Object.entries उपयोग कर सकते हैं:

for (const [key, value] of Object.entries(obj)) { }

या

Object.entries(obj).forEach(([key, value]) => ...)

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

for (const value of Object.values(obj)) { }

या

Object.values(obj).forEach(value => ...)

उपर्युक्त उत्तर थोड़ा परेशान हैं क्योंकि यह सुनिश्चित करने के बाद कि आप एक ऑब्जेक्ट सुनिश्चित करते हैं, आप लूप के अंदर क्या करते हैं, इसकी व्याख्या नहीं करते हैं: आप इसे सीधे स्वीकार नहीं करते हैं! आप वास्तव में केवल कुंजी को वितरित कर रहे हैं जिसे आपको ओबीजे पर आवेदन करने की आवश्यकता है:

var obj = {
  a: "foo",
  b: "bar",
  c: "foobar"
};

// We need to iterate the string keys (not the objects)
for(var someKey in obj)
{
  // We check if this key exists in the obj
  if (obj.hasOwnProperty(someKey))
  {
    // someKey is only the KEY (string)! Use it to get the obj:
    var myActualPropFromObj = obj[someKey]; // Since dynamic, use [] since the key isn't literally named "someKey"

    // NOW you can treat it like an obj
    var shouldBeBar = myActualPropFromObj.b;
  }
}

यह सभी ईसीएमए 5 सुरक्षित है। राइनो जैसे लंगड़े जेएस संस्करणों में भी काम करता है;)


गुणों पर hasOwnProperty लिए इस अतिरिक्त hasOwnProperty जांच की आवश्यकता है:

for (var property in object) {
    if (object.hasOwnProperty(property)) {
        // do stuff
    }
}

यह आवश्यक है क्योंकि किसी ऑब्जेक्ट के प्रोटोटाइप में उस ऑब्जेक्ट के लिए अतिरिक्त गुण होते हैं जो तकनीकी रूप से ऑब्जेक्ट का हिस्सा होते हैं। ये अतिरिक्त गुण मूल ऑब्जेक्ट क्लास से विरासत में प्राप्त होते हैं, लेकिन फिर भी object गुणधर्म हैं।

hasOwnProperty बस यह देखने के लिए जांच करता है कि यह इस वर्ग के लिए विशिष्ट संपत्ति है, और बेस क्लास से विरासत में नहीं मिला है।


जावास्क्रिप्ट 1.8.5 के रूप में आप ऑब्जेक्ट पर परिभाषित गुणों का एक ऐरे प्राप्त करने के लिए Object.keys(obj) का उपयोग कर सकते हैं (वे जो obj.hasOwnProperty(key) लिए सत्य obj.hasOwnProperty(key) )।

Object.keys(obj).forEach(function(key,index) {
    // key: the name of the object key
    // index: the ordinal position of the key within the object 
});

फॉर-इन लूप का उपयोग करने से यह बेहतर (और अधिक पठनीय) है।

यह इन ब्राउज़रों पर समर्थित है:

  • फ़ायरफ़ॉक्स (गीको): 4 (2.0)
  • क्रोम: 5
  • इंटरनेट एक्सप्लोरर 9

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… जानकारी के developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… देखें।


डोमिनिक का जवाब सही है, मैं इसे इस तरह से करना पसंद करता हूं, क्योंकि इसे पढ़ने के लिए क्लीनर है:

for (var property in object) {
    if (!object.hasOwnProperty(property)) continue;

    // Do stuff...
}

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

मान लीजिए कि आपके पास JSON ऑब्जेक्ट है जैसे:

var example = {
    "prop1": "value1",
    "prop2": [ "value2_0", value2_1"],
    "prop3": {
         "prop3_1": "value3_1"
    }
}

अपने 'गुण' के माध्यम से पुन: प्रयास करने का गलत तरीका:

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        recursivelyIterateProperties(jsonObject[prop]);
    }
}

जब आप prop1 और prop2 और prop2 के गुणों के माध्यम से पुनरावृत्ति करते हैं तो कंसोल लॉगिंग 0 , 1 इत्यादि को देखकर आपको आश्चर्य हो सकता है। वे वस्तुएं अनुक्रम हैं, और अनुक्रम की अनुक्रमणिका जावास्क्रिप्ट में उस वस्तु के गुण हैं।

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

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        if (!(typeof(jsonObject[prop]) === 'string')
            && !(jsonObject[prop] instanceof Array)) {
                recursivelyIterateProperties(jsonObject[prop]);

            }

     }
}

यदि आपका पर्यावरण ES2017 का समर्थन करता है तो मैं ऑब्जेक्ट.इन्रीज़ की अनुशंसा करता हूं :

Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`);
});

जैसा कि Mozillas ऑब्जेक्ट .entries () दस्तावेज में दिखाया गया है:

ऑब्जेक्ट.एन्ट्रीज़ () विधि किसी दिए गए ऑब्जेक्ट की अपनी समृद्ध संपत्ति [कुंजी, मान] जोड़ों की एक सरणी देता है, जो उसी क्रम में प्रदान की जाती है ... लूप में (अंतर यह है कि फॉर-इन लूप एन्युमरेट्स प्रोटोटाइप श्रृंखला में गुण भी)।

मूल रूप से Object.entries के साथ हम निम्नलिखित अतिरिक्त कदम से गुजर सकते हैं जो पुराने के साथ आवश्यक है ... लूप में:

// This step is not necessary with Object.entries
if (object.hasOwnProperty(property)) {
  // do stuff
}

यह for...in statement ( MDN , ईसीएमएस्क्रिप्ट स्पेक )।

आप इसे " ओबीजे ऑब्जेक्ट में प्रत्येक प्रॉपर्टी के लिए पढ़ सकते हैं, प्रत्येक प्रॉपर्टी को प्रोपटी वैरिएबल में बदले में असाइन करें"।


यहां मैं प्रत्येक नोड को पुन: सक्रिय कर रहा हूं और सार्थक नोड नाम बना रहा हूं। यदि आप नोटिस करते हैं, उदाहरण के लिए ऐरे और exampleOf ऑब्जेक्ट बहुत अधिक वही काम करता है (मेरे आवेदन में, हालांकि मैं अलग तर्क दे रहा हूं)

function iterate(obj,parent_node) {
    parent_node = parent_node || '';
    for (var property in obj) {
        if (obj.hasOwnProperty(property)) {
            var node = parent_node + "/" + property;
            if(obj[property] instanceof Array) {
                //console.log('array: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            } else if(obj[property] instanceof Object){
                //console.log('Object: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            }
            else {
                console.log(node + ":" + obj[property]);
            }
        }
    }
}

नोट - मैं ओन्ड्रेज सेवज्दार के जवाब से प्रेरित हूं। लेकिन इस समाधान में बेहतर प्रदर्शन और कम संदिग्ध है


रिकर्सिव तरीका भी जोड़ना:

function iterate(obj) {
    // watch for objects we've already iterated so we won't end in endless cycle
    // for cases like var foo = {}; foo.bar = foo; iterate(foo);
    var walked = [];
    var stack = [{obj: obj, stack: ''}];
    while(stack.length > 0)
    {
        var item = stack.pop();
        var obj = item.obj;
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                  // check if we haven't iterated through the reference yet
                  var alreadyFound = false;
                  for(var i = 0; i < walked.length; i++)
                  {
                    if (walked[i] === obj[property])
                    {
                      alreadyFound = true;
                      break;
                    }
                  }
                  // new object reference
                  if (!alreadyFound)
                  {
                    walked.push(obj[property]);
                    stack.push({obj: obj[property], stack: item.stack + '.' + property});
                  }
                }
                else
                {
                    console.log(item.stack + '.' + property + "=" + obj[property]);
                }
            }
        }
    }
}

उपयोग:

iterate({ foo: "foo", bar: { foo: "foo"} }); 

स्वीकार्य उत्तर को और परिशोधित करने के लिए यह ध्यान देने योग्य है कि यदि आप ऑब्जेक्ट को एक var object = Object.create(null) साथ तत्काल करते हैं तो object.hasOwnProperty(property) ट्रिगर करेगा। तो सुरक्षित पक्ष पर रहने के लिए, आपको इसे प्रोटोटाइप से कॉल करने की आवश्यकता होगी:

for (var property in object) {
    if (Object.prototype.hasOwnProperty.call(object, property)) {
        // do stuff
    }
}

Object.keys(obj).forEach(key =>
  console.log(`key=${key} value=${obj[key]}`)
);





object