8

How can I access a multi-level property if I am using a variable as the key?

This is not working:

var obj = {
    first: {thirst: "yo"},
    second: {beckon: "dud"}
}
var key = "first.thirst";
var result = obj[key];
EricC
  • 5,720
  • 13
  • 52
  • 71
  • 2
    You cannot, unless you use `eval` or write a custom function that traverses the tree. – Rob W Jun 14 '14 at 16:10
  • Put this in an answer, with an example of how it is done, and I can accept it as an answer :) – EricC Jun 14 '14 at 16:11

3 Answers3

20

When you use a string as a property name in JavaScript, there are no characters that are off-limits: including the period. So you can easily have an object property like this:

var o = {
    'first.second.third': 'value';
}

Given this, it's clearly not possible to implement your solution.

However, as long as you don't use periods in your property naming, you can create a function that does this:

function resolve(obj, path){
    path = path.split('.');
    var current = obj;
    while(path.length) {
        if(typeof current !== 'object') return undefined;
        current = current[path.shift()];
    }
    return current;
}

Then you could call:

var key = "first.thirst";
var result = resolve(obj, key);
Ramy Tamer
  • 618
  • 1
  • 7
  • 16
Ethan Brown
  • 26,892
  • 4
  • 80
  • 92
6

You can traverse the tree, as @RobW said:

var traverse = function (obj, keys) {
    return keys.split('.').reduce(function (cur, key) {
        return cur[key];
    }, obj);
};

var obj = {
    first: { thirst: 'yo' },
    second: { beckon: 'dud' }
};
var keys = 'first.thirst';
console.log(traverse(obj, keys));
Danilo Valente
  • 11,270
  • 8
  • 53
  • 67
  • Oh, no easy one-line fix :( But at least this will work! Thanks to you all! – EricC Jun 14 '14 at 16:17
  • Two comments. First, `traverse` is a poor name: the fact that this function is traversing the object tree is only an implementation detail. What it's actually doing is resolving a path within the object; it just so happens to be using an abortive depth-first traversal. Secondly, this function will throw an exception if the path isn't valid. Perhaps that's what you want, but in JavaScript, usually not. Otherwise, nice work! – Ethan Brown Jun 14 '14 at 16:22
1
function getMultiLevelProp(obj, key){
if(typeof obj == "object"){
    var keyQueue = key.split(".").reverse();

    var tempVal = obj, currentKey;
    while((currentKey = keyQueue.pop()) != undefined)
            tempVal = tempVal[currentKey];

    return tempVal;
}

return false;}

this could work

hparcalar
  • 86
  • 3