4

Say I have an object like this (simplified):

var options = {
    boxes: {
        size: {
            x: 15,
            y: 18
        },
    shadow: {
        [...]
    }
};

And I have an array of names:

var names = ['boxes', 'size', 'x'];

What is an easy way to get/set a value inside the object according to the array, in this example it would be:

options.boxes.size.x = somevalue;

Any ideas?

2 Answers 2

4

There's no easy, built-in method for doing this. You'd have to write your own method:

function getPath(obj, props) {
    for(var i = 0; i < props.length; i++) {
        if (props[i] in obj) {
            obj = obj[props[i]];
        } else {
            return; // not found
        }
    }

    return obj;
}

function setPath(obj, value, props) {
    for(var i = 0; i < props.length - 1; i++) {
        if (props[i] in obj) {
            obj = obj[props[i]];
        } else {
            return; // not found
        }
    }

    obj[props[i]] = value;
}

alert(getPath(options, names)); // 15
setPath(options, 25, names);  
alert(getPath(options, names)); // 25
Sign up to request clarification or add additional context in comments.

Comments

4

Just use a loop that iterates the names and grabs the next nested object for the current name. Either a falsey value or the end of the array should halt the loop.

var obj = options;
var i = 0;

while (obj && i < names.length)
    obj = obj[names[i++]];

Or simply use .reduce()

names.reduce(function(obj, name) {
    return obj && obj[name];
}, options);

And of course you can name and reuse the function if you prefer.

function toPropertyIn(obj, name) {
    return obj && obj[name];
}

names.reduce(toPropertyIn, options);

To make a getter/setter:

function nestedProp(obj, names, value) {
    if (arguments.length > 1)
        var setProp = names.pop();

    var res = names.reduce(function(obj, name) {
        return obj && obj[name];
    }, options);

    if (res && setProp !== undefined)
        res[setProp] = value;
    else
        return res;
}


nestedProp(options, names, "foo"); // to set

var val = nestedProp(options, names); // to get

2 Comments

the second option looks interesting, I will check it out. Thanks!
@LarsEbert: I missed the "set" part. Updated with a single function that'll handle both.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.