1

I have a for loop which should loop through an object. But this object can have many other object levels inside it. How can I make a function that should make for loops inside for loops as many levels deeps as I want?

Something like this, where the lvl variable would be the number of levels it should dive in:

var lvl = 5;

for (var i = 0; i < groups.length; i++) {
    var groups = groups[i];

    for (var i = 0; i < groups.length; i++) {
        var groups = groups[i];

        for (var i = 0; i < groups.length; i++) {
            var groups = groups[i];

        }
    }
}

For example, if I have the following object tree:

var foo = {
  child: {
    grand:{
      greatgrand: {
      }
    }
  }
}

How can I console log all the object tree names just by diving to a specific level in the foo object?

dive(2); // would dive to level two (grand)

// would return the following in the console
child
grand
5
  • 5
    You should look into recursive functions Commented Sep 11, 2015 at 23:49
  • You need separate variables for each nested for loop so one loop is not overwriting the variables from the others or you can make a function to do the looping and call it recursively. Commented Sep 11, 2015 at 23:52
  • Do you have an array or an object? Commented Sep 11, 2015 at 23:56
  • Choose a different variable name for each loop. JavaScript only has a function (and global) variable scope so every i (and groups) represents the same variable and the multiple occurrences of var is irrelevant. Search for "variable hoisting" for more details. (With that aside, recursion is pretty natural for "N-levels" although using a stack would be another solution.) Commented Sep 12, 2015 at 0:02
  • Wrt. variable scopes: stackoverflow.com/questions/500431/… , stackoverflow.com/questions/30575151/… Commented Sep 12, 2015 at 0:03

2 Answers 2

2

Here you go. I have coded a recursive function which will iterate an object graph. You can provide a depth argument to the traverse function.

A JSFiddle is here. Please check the developer tools console for output.
A fiddle with indentation added is here

var obj = {
firstName: "John",
lastName: "Doe",
address1A: {
    street: "120 Washington St",
    city: "Mountain View",
    state: "CA",
    address2A: {
        street: "100 Washington st",
        city: "Mountain View",
        state: "CA",
        address3A: {
            street: "150 Washington st",
            city: "Mountain View",
            state: "CA",
            address4A: {
                street: "150 Washington st",
                city: "Mountain View",
                state: "CA",
            }
        }
    }
},
address1B: {
    street: "120 Washington St",
    city: "Mountain View",
    state: "CA",
    address2B: {
        street: "100 Washington st",
        city: "Mountain View",
        state: "CA",
        address3B: {
            street: "150 Washington st",
            city: "Mountain View",
            state: "CA",
            address4B: {
                street: "150 Washington st",
                city: "Mountain View",
                state: "CA",
            }
        }
    }
}
};

function traverse(initObj, depth) {
     depthTraversal(initObj, depth, 1);
}

function depthTraversal(objArg, depthArg, counterArg) {
    //create a closure for remembering loop variables
    return (function (myObj, myDepth, counter) {
        //console.log(myDepth + " - " + counter);
        if (myDepth < counter) {
          return;
        }
       //console.log(myObj);
       for (var prop in myObj) {
          //console.log(prop + " :" + typeof (myObj[prop]));
          if (myObj.hasOwnProperty(prop)) {
             if (typeof (myObj[prop]) === "object") {
                console.log(prop);
                depthTraversal(myObj[prop], myDepth, counter + 1);
             }
          }
      }
}(objArg, depthArg, counterArg)); //IIFE
};


traverse(obj, 4);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I'll review your solution to better understand how to use this :)
2

A recursive function--a function that calls itself--is the way to go. You'd want something like this:

/* pseudo-code; this will not run */
function processThing(thing) {
  if (thing is an object) {
    // process all of thing's properties
    for (property in thing) {
      processThing(property);
    }
  }
  else {
    // process thing as a value
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.