How to set object property (of object property of..) given its string name in JavaScript?

后端 未结 14 1887
离开以前
离开以前 2020-11-22 02:20

Suppose we are only given

var obj = {};
var propName = \"foo.bar.foobar\";

How can we set the prop

相关标签:
14条回答
  • 2020-11-22 02:59

    Here is a simple function to do that using reference.

        function setValueByPath (obj, path, value) {
            var ref = obj;
    
            path.split('.').forEach(function (key, index, arr) {
                ref = ref[key] = index === arr.length - 1 ? value : {};
            });
    
            return obj;
        }
    
    0 讨论(0)
  • 2020-11-22 02:59

    I was looking for an answer that does not overwrite existing values and was easily readable and was able to come up with this. Leaving this here in case it helps others with the same needs

    function setValueAtObjectPath(obj, pathString, newValue) {
      // create an array (pathComponents) of the period-separated path components from pathString
      var pathComponents = pathString.split('.');
      // create a object (tmpObj) that references the memory of obj
      var tmpObj = obj;
    
      for (var i = 0; i < pathComponents.length; i++) {
        // if not on the last path component, then set the tmpObj as the value at this pathComponent
        if (i !== pathComponents.length-1) {
          // set tmpObj[pathComponents[i]] equal to an object of it's own value
          tmpObj[pathComponents[i]] = {...tmpObj[pathComponents[i]]}
          // set tmpObj to reference tmpObj[pathComponents[i]]
          tmpObj = tmpObj[pathComponents[i]]
        // else (IS the last path component), then set the value at this pathComponent equal to newValue 
        } else {
          // set tmpObj[pathComponents[i]] equal to newValue
          tmpObj[pathComponents[i]] = newValue
        }
      }
      // return your object
      return obj
    }
    
    0 讨论(0)
  • 2020-11-22 03:00

    A very straightforward one.

    No recursions or callbacks overhead.

    function setDeepVal(obj, path, val) {
      var props = path.split('.');
      for (var i = 0, n = props.length - 1; i < n; ++i) {
        obj = obj[props[i]] = obj[props[i]] || {};
      }
      obj[props[i]] = val;
      return obj;
    }
    
    
    
    // TEST
    var obj = { hello : 'world' };
    setDeepVal(obj, 'foo.bar.baz', 1);
    setDeepVal(obj, 'foo.bar2.baz2', 2);
    console.log(obj);

    0 讨论(0)
  • 2020-11-22 03:01

    Here's a simple method that uses a scoped Object that recursively set's the correct prop by path.

    function setObjectValueByPath(pathScope, value, obj) {
      const pathStrings = pathScope.split('/');
      obj[pathStrings[0]] = pathStrings.length > 1 ?
        setObjectValueByPath(
          pathStrings.splice(1, pathStrings.length).join('/'),
          value,
          obj[pathStrings[0]]
        ) :
        value;
      return obj;
    }
    
    0 讨论(0)
  • 2020-11-22 03:05

    Here is a get and set function i just compiled from a couple of threads + some custom code.

    It will also create keys that don't exist on set.

    function setValue(object, path, value) {
        var a = path.split('.');
        var o = object;
        for (var i = 0; i < a.length - 1; i++) {
            var n = a[i];
            if (n in o) {
                o = o[n];
            } else {
                o[n] = {};
                o = o[n];
            }
        }
        o[a[a.length - 1]] = value;
    }
    
    function getValue(object, path) {
        var o = object;
        path = path.replace(/\[(\w+)\]/g, '.$1');
        path = path.replace(/^\./, '');
        var a = path.split('.');
        while (a.length) {
            var n = a.shift();
            if (n in o) {
                o = o[n];
            } else {
                return;
            }
        }
        return o;
    }
    
    0 讨论(0)
  • 2020-11-22 03:10

    Here's one that returns the updated object

    function deepUpdate(value, path, tree, branch = tree) {
      const last = path.length === 1;
      branch[path[0]] = last ? value : branch[path[0]];
      return last ? tree : deepUpdate(value, path.slice(1), tree, branch[path[0]]);
    }
    
    const path = 'cat.dog';
    const updated = deepUpdate('a', path.split('.'), {cat: {dog: null}})
    // => { cat: {dog: 'a'} }
    
    0 讨论(0)
提交回复
热议问题