Fred A
Fred A

Reputation: 1764

Recursive function for looping through JSON object

I read about how to iterate through a multi levels JSON object that contains both object and array in it using recursive technique.

Lets say the object in question is as follow

{
    "data":[
        {
            "Name": "Name1",
            "Id": "Id1",
            "Prop": {
                "isProp":""
                "isClass":"Yes"
            }
        },
        {
            "Name": "Name2",
            "Id": "Id2",
            "Prop": {
                "isProp":"No"
                "isClass":"Yes"
            }
        },
        {
            "Name": "Name3",
            "Id": "Id3",
            "Prop": [
                {
                    "isProp":"Maybe"
                    "isClass":""
                },
                {
                    "isProp":"No"
                    "isClass": null
                },
            ]
        }
    ]
}

Using the above as example, and if i want to change the empty or null value into a valid string, is below the right way to perform the recursive technique to iterate through the JSON object?

$.ajax(somethingHere).success(function(data){
    !(Array.isArray(data)) ? iterateObj(data) : $.each(data, function(){ iterateObj(this) });
});

function iterateObj(data){
    for(var key in data){
        if (data.hasOwnProperty(key)){
            if (!(Array.isArray(data[key]))){
                if (!data[key]){
                    data[key] = "Empty";
                }
            }
            else {
                $.each(data, function(){ iterateObj(this) })
            }
        }
    }
}

I tried the above but didn't work. Not sure where is my mistake tho. If possible, i'd like the function above to be able to iterate through any JSON object of any level and with/without object or array in it.

And i read somewhere that using Underscore/Lo-dash's pick/deepClone (not sure if i got it right) makes iteration (through any levels, and to any inner object/array inside the JSON object) much easier, is this true?

Thanks

Upvotes: 1

Views: 2928

Answers (2)

Elias
Elias

Reputation: 95

You are on the right way with your code. Only a few things to add:
- Recursive function should return the value
- Array.isArray(data[key]) is not a sufficient way to test for further iterations, use data[key] !== null && typeof data[key] === 'object' instead

So your function might look like this:

$.ajax(somethingHere).success(function(data){
    data = iterateObj(data);
});

function iterateObj(data) {
    for(var key in data){
        if (data.hasOwnProperty(key)) {
            if (data[key] !== null && typeof data[key] === 'object') {
                data[key] = iterateObj(data[key]);
            }
            else {
                if ( ! data[key]){
                    data[key] = "Empty";
                }
            }
        }
    }
    return data;
}

Also, your sample data object has invalid syntax (missing commas).

Upvotes: 2

vijayP
vijayP

Reputation: 11502

Updated iterateObj() function to take care of other data types

function iterateObj(dupeObj) {
    var retObj = new Object();
    if (typeof (dupeObj) == 'object') {
        if (typeof (dupeObj.length) == 'number')
            var retObj = new Array();

        for (var objInd in dupeObj) {
            if (dupeObj[objInd] == null)
                dupeObj[objInd] = "Empty";
            if (typeof (dupeObj[objInd]) == 'object') {
                retObj[objInd] = iterateObj(dupeObj[objInd]);
            } else if (typeof (dupeObj[objInd]) == 'string') {
                retObj[objInd] = dupeObj[objInd];
            } else if (typeof (dupeObj[objInd]) == 'number') {
                retObj[objInd] = dupeObj[objInd];
            } else if (typeof (dupeObj[objInd]) == 'boolean') {
                ((dupeObj[objInd] == true) ? retObj[objInd] = true : retObj[objInd] = false);
            }       
        }
    }
    return retObj;
}

Upvotes: 0

Related Questions