Henry
Henry

Reputation: 1434

Get element on any level of an object in Javasscript

Given the following:

var a = JSON.parse('{"fst":"data1","snd":{"ind2":"data2"}}');
var index = "fst";
var res = a[index]; //res = data1
var index2 = "????";
var res2 = a[index2]; //res = data2

what should I put on index2 so res2 equals data2?

I'm looking for a generic syntax that would let me grab an element at ANY level of the parsed json, just by modifying the index string.

(I'm looping through a list of elements from different places/levels of a json derived object to build a table)

Any help would be much appreciated

Upvotes: 1

Views: 179

Answers (3)

Roman
Roman

Reputation: 215

var someObject1 = {};
var someObject2 = {e01: '*', e02: {e03: '*', e04: '*'}, e05: '*'};
var someObject3 = {e01: {e02: {e03: '*'}}};

function setValueByPath(obj, path, value) {
    var pathArray = path.split('.');

    function goDownstears(o, chunk, val) {
        var prop = chunk.shift();

        if(!o.hasOwnProperty(prop)) o[prop] = {};

        o[prop] = (chunk.length > 0) ? goDownstears(o[prop], chunk, val) : val;

        return o;
    }

    obj = goDownstears(obj, pathArray, value);
}

setValueByPath(someObject1, 'e01.e02.e03', 'changed');

setValueByPath(someObject2, 'e02.e04', 'changed');

setValueByPath(someObject3, 'e01.e02.e03', 'changed');
setValueByPath(someObject3, 'e01.e02.e04', 'changed');
setValueByPath(someObject3, 'e02.e01.e01', 'changed');

console.log(someObject1);
console.log(someObject2);
console.log(someObject3);

My question was closed here set an object property with sugar like obj['level1.level2.leve3'] = value

See here http://jsfiddle.net/zafod/RDGwY

This issue is for setting a value, but you can just return an asked property througth iterations

Upvotes: 1

user1726343
user1726343

Reputation:

You're accessing a property of a property, and the syntax reflects this:

var res = a['snd']['ind2'];

There is no way to directly grab the "nested" property directly. If you're allowed to change the original object, you could add shortcut accessors for each object:

//Credit goes to Esailja for the original
function deepAccess(obj) {
    function nestedAccess(o, level) {
        if (typeof o == "object") {
            var level = level || "";
            for (p in o) {
                if (o.hasOwnProperty(p)) {
                    if (level && typeof(o[p]) != "object") {
                        obj[level + "." + p] = o[p];
                    }
                    nestedAccess(o[p], (level ? level + "." : "") + p);
                }
            }
        }
    }
    nestedAccess(obj);
}

deepAccess(a);

a["snd.ind2"];

Upvotes: 2

Esailija
Esailija

Reputation: 140228

You need a function for that

function deepAccess( obj, str ) {
    var parts = str.split("."),
        cur = obj;
    for( var i = 0; i < parts.length; ++i ) {
        cur = cur[parts[i]];    
    }

    return cur;
}

var index = "fst";
deepAccess( a, index ); //"data1"
index = "snd.ind2";
deepAccess( a, index ); //"data2"

Upvotes: 2

Related Questions