4

Is it possible to set a Variable in an Object by an Array of Keys? For example i have this Object:

var obj = {'outer': {'inner': 'value'} };

and want to set the Value selected by an Array of Keys:

var keys = ['outer', 'inner'];

to a new Value 'newValue' in order to get this Result:

obj = {'outer': {'inner': 'newValue'} };

2 Answers 2

2

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.
}
1

The key point here is that an object property can be accessed using property name string: obj.prop <=> obj["prop"].

function SetValueByKeyNames(obj, keys, value) {
  var target = obj;
  for(var i = 0; i < keys.length - 1; i++) {
    target = target[keys[i]];
    if (!target)
      return false;
  }
  target[keys[keys.length - 1]] = value;
  return true;
}

var obj = {'outer': {'inner': 'value'} };
var keys = ['outer', 'inner'];

console.log(obj.outer.inner); // value
SetValueByKeyNames(obj, keys, 'newValue');
console.log(obj.outer.inner); // newValue
2
  • Just saw you beat me to it, we had the same idea :), +1.
    – nem035
    Commented Feb 9, 2016 at 2:52
  • Come on, not even a semblance of an explanation?
    – user4639281
    Commented Feb 9, 2016 at 3:06

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.