Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access nested JSON data

Tags:

Let say I have json data like

data = {"id":1,
        "name":"abc",
        "address": {"streetName":"cde",
                    "streetId":2
                    }
        }

Now I am getting fields to be accessed from this json data like : fields = ["id", "name", "address.streetName"]

How could I access third field (address.streetName) from given json data in most efficient way? data.fields[2] doesn't work

One possibility is I construct data[address][streetName] string using a for loop and do eval of that but is there any efficient way of doing this?

like image 547
Abhinav SInghvi Avatar asked Feb 27 '12 10:02

Abhinav SInghvi


People also ask

How do you access nested elements in a JSON object?

Accessing nested json objects is just like accessing nested arrays. Nested objects are the objects that are inside an another object. In the following example 'vehicles' is a object which is inside a main object called 'person'. Using dot notation the nested objects' property(car) is accessed.

How can I access and process nested objects arrays or JSON?

Use console. log or console. dir and inspect the structure of object / array. The property you are trying to access might be actually defined on a nested object / array.


4 Answers

To be honest, I can't understand your problem. JSON is already structured out, why do you need to change the structure?

In you case, I would access it as follows:

data.address.streetName; 

If, by any chance, what you want is to traverse the data, you would need:

function traverse_it(obj){     for(var prop in obj){         if(typeof obj[prop]=='object'){             // object             traverse_it(obj[prop[i]]);         }else{             // something else             alert('The value of '+prop+' is '+obj[prop]+'.');         }     } }  traverse_it(data); 

Update

After reading below, what this user needs seems more obvious. Given property names as a string, s/he wants to access the object.

function findProp(obj, prop, defval){     if (typeof defval == 'undefined') defval = null;     prop = prop.split('.');     for (var i = 0; i < prop.length; i++) {         if(typeof obj[prop[i]] == 'undefined')             return defval;         obj = obj[prop[i]];     }     return obj; }  var data = {"id":1,"name":"abc","address":{"streetName":"cde","streetId":2}}; var props = 'address.streetName'; alert('The value of ' + props + ' is ' + findProp(data, props)); 
like image 193
Christian Avatar answered Nov 09 '22 03:11

Christian


If you use lodash(a very popular utility library), you can use _.get().

e.g.

var data = {   "id":1,   "name": "abc",   "address": {     "streetName": "cde",     "streetId":2   } } _.get(data, 'address.streetName'); // 'cde' _.get(data, ['address', 'streetName']); // 'cde' 

If it involves an array, you can use string path like 'address[0].streetName' as well.

e.g.

var data = {   "id":1,   "name": "abc",   "addresses": [     {       "streetName": "cde",       "streetId": 2     },     {       "streetName": "xyz",       "streetId": 102     },   ] } _.get(data, 'addresses[0].streetName'); // cde _.get(data, [address, 1, streetName]); // xyz 

Internally, it uses toPath() function to convert string path (e.g. address.streetName) into an array (e.g. ['address', 'streetName']), and then uses a function to access the data at the given path within the object.

Other similar utility functions include _.set() and _.has(). Check them out.

like image 43
Brian Park Avatar answered Nov 09 '22 04:11

Brian Park


Long story short, you can use the array notation object[property] instead of object.property; this is specially useful when the keys contains special characters:

var data = {
    "id": 1,
    "name": "abc",
    "address": {
        "streetName": "cde",
        "streetId": 2
    }
}

data.address.streetName;              // (1) dot notation
data["address"]["streetName"];        // (2) array notation
var field = "streetName";
data["address"][field];               // (3) variable inside array notation
var fields = "address.streetName".split(".");
data[fields[0]][fields[1]];           // (4) specific to your question

You can use the typeof operator to check whether a property exists or not before using it:

typeof data["address"]["streetName"]; // returns "string"
typeof data["address"]["foobarblah"]; // returns "undefined"
like image 42
Salman A Avatar answered Nov 09 '22 04:11

Salman A


Your data variable doesn't have a fields property, and that's why data.fields[2] doesn't work. I think what you're trying to do there is data[fields[2]], which would work for a simple object, but you can't index into a complex object like that.

like image 36
Greg B Avatar answered Nov 09 '22 02:11

Greg B