9

Is there are a way to recursively loop over all the nested properties of a JS/jQuery object?

For example, given this object

var x = {
    'name': 'a',
    'level': 1,
    'children': [{
        'name': 'b',
        'level': 2,
        'children': [{
            'name': 'c',
            'level': 3,
            'children': [{
            ...
            }]
        }]},
        ...
    }]
}

how could I loop over the objects named 'a' and their children, 'b' and their children, 'c' and their children, ad infinitum?

5
  • What is your intend for this function? List all the child objects, count them? Commented Sep 6, 2012 at 8:03
  • 2
    10 print "use recursion"; 20 goto 10 Commented Sep 6, 2012 at 8:03
  • check children.lenght if >0 , call your function recursively. Commented Sep 6, 2012 at 8:05
  • @KyorCode The purpose of the function is to do something on a property if it meets certain conditions. It could easily be done if the object structure is known beforehand but as it is, the object structure is variable. Commented Sep 6, 2012 at 8:06
  • @YograjGupta The 'children' property is just an example. I actually do not know which of the properties are object themselves. Commented Sep 6, 2012 at 8:07

5 Answers 5

19

A recursive approach seems best, something like this:

function recursiveIteration(object) {
    for (var property in object) {
        if (object.hasOwnProperty(property)) {
            if (typeof object[property] == "object"){
                recursiveIteration(object[property]);
            }else{
                //found a property which is not an object, check for your conditions here
            }
        }
    }
}

This is a working fiddle

Sign up to request clarification or add additional context in comments.

Comments

1
function iterate(obj){
    for(var key in obj)
    {
        if(typeof(obj["key"]) == "object"){
            iterate(obj["key"]);
        }
        else{
            console.log(key + ": " + obj["key"];
        }
    }

}

Comments

1

Your JSON is not well formatted but you can "visit" each item as below:

<html>
<head>
    <title>test</title>
    <script type="text/javascript">
        var x = {
                "name": "a",
                "level": 1,
                "children": [
                    {
                        "name": "b",
                        "level": 2,
                        "children": [
                            {
                                "name": "c",
                                "level": 3,
                                "children": [
                                    {
                                        "sss": 23
                                    }
                                ]
                            }
                        ]
                    }
                ]
            };

         function visit(obj){
            for(var prop in obj){
                if(typeof(obj[prop]) == 'object'){
                    if(Object.prototype.toString.call(obj[prop]) == '[object Array]'){
                        for(var i = 0; i < obj[prop].length; i++){
                            document.write("<br />the element " + prop + " (array) was visited");
                            visit(obj[prop][i]);                                
                        }
                    }else{
                        document.write("<br />the element " + prop + " (object) was visited");
                        visit(obj[prop]);
                    }
                }else{
                    document.write("<br />the element " + prop + " = " + obj[prop] + " was visited");
                }
            }
        }

        visit(x);

    </script>
</head>
<body>

</body>

3 Comments

typeof array === "object' so you can't test if it's an array that way.
@jfriend00 you're right. This make my answer not so useful and I think I'll remove it.
You don't have to remove it - just fix it: ajaxian.com/archives/…
1

I was originally looking for a way to search a javascript object recursively and I found this post very helpful, in particular Jeroen Moons's answer. I have tweaked it to provide a return object. Input is object to search and a {key:value} object (needle).

function searchObject(object, keyvalue){
    var found = false;
    for (var property in object){
        if (object.hasOwnProperty(property)){
            if (typeof object[property] == 'object'){
                found = searchObject(object[property], keyvalue);
                if (found)
                    return found;
            }else{
                key = Object.keys(keyvalue)[0];
                if (property == key && object[key] == keyvalue[key]){
                    console.log('searchObject ' + keyvalue[key] + ' found');
                    return object;
                }
            }
        }
    }
}

Comments

0
var x = {
    'name': 'a',
    'level': 1,
    'children': [{
        'name': 'b',
        'level' : 2,
        'children' : [{
            'name': 'c',
            'level' : 3,
            'children' : [{
            }]
        }]
    }, {
        'name': 'b2',
        'level' : 2,
        'children' : [{
            'name': 'c2',
            'level' : 3,
            'children' : [{
            }]
        }]
    }]
}
var step = x;
do {
    if (step instanceof Array){
        for (i=0; i < step.length; i++) {
            callback(step[i]);
        }
    }
    else {
        callback(step);
    }
    step = step.children != undefined ? step.children : null;
} while (step);

function callback (element) {
    console.log(element);
}

as long as the structure does not change, you can go down like this.

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.