Skip to content

trouble with recursion; parsing JSON

I have a json object like this:

[{
    "thing": "Top",
    "data": {
        "childs": [{
            "thing": "a",
            "data": {
                "text": "sdfgdg1",
                "morestuff": {
                    "thing": "Top",
                    "data": {
                        "childs": [{
                            "thing": "a",
                            "data": {
                                "text": "sdfg2",
                                "morestuff": "",
                            }
                        },
                        {
                            "thing": "a",
                            "data": {
                                "text": "gfhjfghj3",
                                "morestuff": {
                                    "thing": "Top",
                                    "data": {
                                        "childs": [{
                                            "thing": "a",
                                            "data": {
                                                "text": "asdfsadf 2 4",
                                                "morestuff": {
                                                    "thing": "Top",
                                                    "data": {
                                                        "childs": [{
                                                            "thing": "a",
                                                            "data": {
                                                                "text": "asdfsadf 2 5",
                                                                "morestuff": {
                                                                    "thing": "Top",
                                                                    "data": {
                                                                        "childs": {
                                                                            "thing": "a",
                                                                            "data": {
                                                                                "text": "asdfsadf 2 6",
                                                                                "morestuff": "",
                                                                            },
                                                                            "data": {
                                                                                "text": "asdfsadf 2 6",
                                                                                "morestuff": "",
                                                                            }
                                                                        },
                                                                    }
                                                                },
                                                            }
                                                        }],
                                                    }
                                                },
                                            }
                                        }],
                                    }
                                },
                            }
                        }],
                    }
                },
            }
        },
        {
            "thing": "a",
            "data": {
                "text": "asdfasd1 2",
                "morestuff": {
                    "thing": "Top",
                    "data": {
                        "childs": [{
                            "thing": "a",
                            "data": {
                                "text": "asdfsadf 2 3",
                                "morestuff": "",
                            }
                        }],
                    }
                },
            }
        },
        {
            "thing": "a",
            "data": {
                "text": "dfghfdgh 4",
                "morestuff": "",
            }
        }],
    }
}]  

…and I’m trying to iterate through it and get a total count on the “text” objects.

I can’t seem to be able to get something recursive working.. I think I’m missing a base-level understanding of both json and recursion..

After a couple of days of variations on this:

count=0;
c2=0;
c3=0;
function ra(arr){
    //console.log(arr.data.morestuff)
    if(arr!==undefined && arr.data && arr.data.morestuff===""){
        c3++;

    }else if((arr && arr.data && typeof arr.data.morestuff==="object")){
            if(arr.data.morestuff.data.childs.length>1){
                for(var w=0;w<arr.data.morestuff.data.childs.length;w++){
                    count+=ra(arr.data.morestuff.data.childs[w])
                }
            }else{
                count+=ra(arr.data.morestuff.data.childs[0])
            }
    }
         return(c3)
}
countn=0;//top morestuff with no morestuff
tot=0;
function reps(obj){
tot=obj.data.childs.length;
console.log("tot="+tot)
    for(var x=0;x<tot;x++){
        tot+=ra(obj.data.childs[x])
        c3=0
        if(tot>1000){//trying to prevent a runaway loop somehwere
            break;
        }
    }
    console.log(tot)
}

reps(json[0]); 

I’ve come to the conclusion that I just don’t know. I get all kinds of different results; some have come close by adding together the returns from the ra method, but nothing consistant (i.e. wrong) and always off by at least a few.

The JSON is consistent, though there are un-known numbers of children and childrens children which is why I’m looking to recursion.

Here is a fiddle: http://jsfiddle.net/CULVx/

Ideally, I’d like to count each text object, its’ relative position, and the number of children it has, but I figure I can mess with getting that stuff into an array if I could just get the counting working…

NB: I’ve tried jsonParse and other libraries to no avail. In particular, jsonParse throws an Object has no method "match" error when trying to use it on this json.

Answer

If you just want all "text" properties at any depth, then this should be sufficient: http://jsfiddle.net/QbpqT/.

You have a property key twice, though ("data" in the most nested object). Since an object cannot contain two properties with the same key, so you actually have 9 "text" properties; not 10.

var count = 0;

function iterate(obj) {
    for(var key in obj) { // iterate, `key` is the property key
        var elem = obj[key]; // `obj[key]` is the value

        if(key === "text") { // found "text" property
            count++;
        }

        if(typeof elem === "object") { // is an object (plain object or array),
                                       // so contains children
            iterate(elem); // call recursively
        }
    }
}

iterate(data); // start iterating the topmost element (`data`)

console.log(count); // 9