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
2 Answers 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);
1 Comment
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
}
}
forloop 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.i(andgroups) represents the same variable and the multiple occurrences ofvaris 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.)