简体   繁体   中英

Loop through object with nested $.each

I'm having trouble looping through an object using a nested $.each. The object is a series of object of the same type/class nested under rootObject.

The object

var rootObject ={};

rootObject.reportObject1.name = "reportObject1 Name";
rootObject.reportObject1.prop1 = "reportObject1 Prop1_Value";
rootObject.reportObject1.prop2 = "reportObject1 Prop2_Value";

rootObject.reportObject1.reportObjectA.name = "reportObjectA Name";
rootObject.reportObject1.reportObjectA.prop1 = "reportObjectA Prop1_Value";
rootObject.reportObject1.reportObjectA.prop2 = "reportObjectA Prop2_Value";

The Loop

$.each(rootObject, function(index0, value0){
  console.log(value0.name);

  $.each(value0, function(index1, value1){
    console.log(value1.name);
  }

}

The Problem

  1. value1.name is returning object properties other than name in the loop. It's seemingly attempting to return value.name for prop1 & prop2 , resulting in "undefined" values.

  2. When looking into the value of value0 during debugging, value0 appears to loose its value as it enters the nested loop. Ie at console.log(value1.name) , value0 , from the parent loop, becomes undefined ;

  3. When looking into the child loop ( index1, value1 ) during debugging, I see that value1 now equals value0.name , and index1 equals "name".

You can automatically define properties one level deep, but for two you need to stop and instantiate the parent:

var rootObject ={};

rootObject.reportObject1 = {}; // HERE
rootObject.reportObject1.name = "reportObject1 Name";
rootObject.reportObject1.prop1 = "reportObject1 Prop1_Value";
rootObject.reportObject1.prop2 = "reportObject1 Prop2_Value";

rootObject.reportObject1.reportObjectA = {}; // and HERE
rootObject.reportObject1.reportObjectA.name = "reportObjectA Name";
rootObject.reportObject1.reportObjectA.prop1 = "reportObjectA Prop1_Value";
rootObject.reportObject1.reportObjectA.prop2 = "reportObjectA Prop2_Value";

Without that, none of these properties are actually getting defined, leading to your undefined results.

The next issue is another syntax problem: you're missing closing parentheses on the two $.each() calls:

$.each(rootObject, function(index0, value0){
  console.log(value0.name);

  $.each(value0, function(index1, value1){
    console.log(value1.name);
  }); // HERE

}); // and HERE

With these two fixes, your console output shows:

reportObject1 Name
undefined (x3)
reportObjectA Name

To get the correct output, or at least some sample output, you could use this little gem ( from here ). Because your structure could potentially have more than two levels, recursion seems appropriate here.

function enumerate(o,s){

    //if s isn't defined, set it to an empty string
    s = typeof s !== 'undefined' ? s : "";

    //iterate across o, passing keys as k and values as v
    $.each(o, function(k,v){

        //if v has nested depth
        if(typeof v == "object"){

            //write the key to the console
            console.log(s+k+": ");

            //recursively call enumerate on the nested properties
            enumerate(v,s+"  ");

        } else {

            //log the key & value
            console.log(s+k+": "+String(v));
        }
    });
}

If you try enumerate(rootObject) , you will get:

reportObject1: 
   name: reportObject1 Name
   prop1: reportObject1 Prop1_Value
   prop2: reportObject1 Prop2_Value
   reportObjectA: 
     name: reportObjectA Name
     prop1: reportObjectA Prop1_Value
     prop2: reportObjectA Prop2_Value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM