What you can do is iterate over the array of keys, making sure that each key exists and leads to another object, until you reach the last key, which you use to set the new value.
function setVal(obj, keys, value) {
var o = obj,
len = keys.length;
// iterate through all keys, making sure each key exists and points to an object
for (var i = 0; i < len - 1; i++) {
var key = keys[i];
// check if the current key exists and is an object
if (obj.hasOwnProperty(key) && typeof obj[key] === 'object' && obj[key]) {
o = o[key];
} else {
// return false or throw an error cause the key is not an object or is missing.
}
}
// update the value at the last key
o[keys[len - 1]] = value;
}
Here's a running example:
function setVal(obj, keys, value) {
var o = obj,
len = keys.length;
for (var i = 0; i < len - 1; i++) {
var key = keys[i];
if (obj.hasOwnProperty(key) && typeof obj[key] === 'object' && obj[key]) {
o = o[key];
} else {
throw new Error('Key ' + key + ' is not an object or is missing.');
}
}
o[keys[len - 1]] = value;
}
var obj = {
'outer': {
'inner': 'value'
}
};
var validKeys = ['outer', 'inner'];
var invalidKeys = ['outer', 'inner', 'extra'];
console.log('Setting valid keys');
setVal(obj, validKeys, 'new value');
console.log(obj);
console.log('Setting invalid keys');
setVal(obj, invalidKeys, 'new value');
console.log(obj);
If you want to have your method only update existing key values and not set new ones, you can wrap the last statement in setVal
using hasOwnProperty
:
// if object already has the last key, update its value
if (o.hasOwnProperty(keys[len - 1])) {
o[keys[len - 1]] = value;
} else {
// throw an error or return false since the last key doesn't exist.
}