5

a web service returns the following nested json object:

{"age":"21-24","gender":"Male","location":"San Francisco, CA","influencer score":"70-79","interests":{"Entertainment":{"Celebrities":{"Megan Fox":{},"Michael Jackson":{}},},"Social Networks & Online Communities":{"Web Personalization": {},"Journals & Personal Sites": {},},"Sports":{"Basketball":{}},},"education":"Completed Graduate School","occupation":"Professional/Technical","children":"No","household_income":"75k-100k","marital_status":"Single","home_owner_status":"Rent"}

i just want to iterate through this object without specifying property name, i tried the following code :

for (var data in json_data) {
    alert("Key:" + data + " Values:" + json_data[data]);
}

however it prints value as [object Object] if it's a nested value, is there any way to keep iterating deeper into nested values ?

palswim
  • 11,856
  • 6
  • 53
  • 77
Amr Ellafy
  • 730
  • 8
  • 26

6 Answers6

7

Try this:

function iter(obj) {
  for (var key in obj) {
    if (typeof(obj[key]) == 'object') {
      iter(obj[key]);
    } else {
      alert("Key: " + key + " Values: " + obj[key]);
    }
  }
}

BB: added + to prevent error.

Barrett
  • 117
  • 1
  • 6
g.d.d.c
  • 46,865
  • 9
  • 101
  • 111
3

You can do this recursively.

function alertobjectKeys(data) {
  for (var key in data) {
    if (typeof(data[key]) == "object" && data[key] != null) {
      alertobjectKeys(data[key]);
    } else {
      alert("Key:" + key + " Values:" + data[key]);
    }
  }
}
John Hartsock
  • 85,422
  • 23
  • 131
  • 146
  • Inside your nested call you need data[key] - otherwise you're simply reiterating the same object you received. – g.d.d.c Nov 05 '10 at 21:03
0

You can always create a recursive function:

function alertObj(obj) {
    for (var data in obj) {
        if(typeof(obj[data]) === "object")
            alertObj(obj[data]);
        else
            alert("Key:" + data + " Values:" + obj[data]);
    }
}

As long as you aren't worried about recursing too far (which you probably don't need to with JSON objects).

You can also do this with a queue or stack (array) structure:

function alertObj_queue(obj) { // Breadth-first
    var arrPrint = [{key:"Object", data:obj}]; // Initialize array with original object

    for(var i = 0; i < arrPrint.length; i++) {
        if(typeof(arrPrint[i].data) === "object") {
            for(var k in arrPrint[i].data) { // Add each to end of array
                arrPrint.push({key: k, data: arrPrint[i].data[k]});
            }
            alert("Object key: " + arrPrint[i].key);
        } else {
            alert("Key:" + arrPrint[i].key + " Values:" + arrPrint[i].data);
        }
    }
}

function alertObj_stack(obj) { // Depth-first
    var arrPrint = [{key:"Object", data:obj}]; // Initialize array with original object

    while(arrPrint.length) {
        var o = arrPrint.pop();
        if(typeof(o.data) === "object") {
            for(var k in o.data) { // Add each to end of array
                arrPrint.push({key: k, data: o.data[k]});
            }
            alert("Object key: " + o.key);
        } else {
            alert("Key:" + o.key + " Values:" + o.data);
        }       
    }
}
palswim
  • 11,856
  • 6
  • 53
  • 77
  • your code is not right. You pass in obj but use json_data in your for loop....json_data is undefined. – John Hartsock Nov 05 '10 at 21:04
  • unfortunately both does not work, they only go through the 1st level – Amr Ellafy Nov 06 '10 at 00:07
  • @HeoQue: You only see alerts on the first level because in your data, everything below the first level is an object, so the loop will look at "Sports" and see that it's an object, then go down to "Basketball" and see that it's also an object, so it won't `alert` for any of those. It would probably make things easier to have some of your JSON data as arrays ("Sports", "Celebrities", etc.). – palswim Nov 08 '10 at 18:29
0

This of course requires recursion

(function(obj) {
  for (var key in obj) if (obj.hasOwnProperty(key)) {
    if (typeof obj[key] == 'object' && obj[key] !== null)
      arguments.callee(obj[key]);
    else 
      alert("Key: " + key + " Values: " + obj[key]);
  }
)(json_data));
MooGoo
  • 46,796
  • 4
  • 39
  • 32
0
function recursiveParse(variable) { 
    for (var key in variable) {
        if ((is_object(variable[key])) || (is_array(variable[key]))) {
            recursiveParse(variable[key]);
        } else {
            // Process variable here
        }
    }
}

Then just call that function with the parameter being the json data, it will parse through the remaining objects and arrays recursively.

Anthony Corbelli
  • 877
  • 4
  • 10
0

I'm guessing that in your request (assuming it's Ajax) you aren't specifying the dataType to be returned as 'json'.

Stormbytes
  • 189
  • 4
  • 11