如何通过提供键值数组动态地修改对象值?

时间:2019-05-16 19:03:51

标签: javascript arrays reactjs object

因为我要处理一个相对较大的对象,所以我希望能够通过定义“路径”来动态修改我的对象值。

let a="x", b="y", c="z"

let objKeys = [a, b, c]

let value = 5

obj = {x: 
        {y: 
          {z: 1
          }
         }
       }


我希望能够实现这一目标。

obj[a][b][c] = value;

有没有办法做到这一点?我尝试过obj(eval(`["a"]["b"]["c"]`)) = value,但它说“作业中的左侧无效”。

4 个答案:

答案 0 :(得分:2)

通过使用键数组和对象,可以通过使用每个键访问该对象并返回最终对象来减少该对象。然后使用最后一个键并指定值。

这种方法将新对象添加为未提供属性的默认值。

function setValue(object, keys, value) {
    var target = keys.pop();
    keys.reduce((o, k) => o[k] = o[k] || {}, object)[target] = value;
}

var obj = { x: { y: { z: 1 } } };

setValue(obj, ['x', 'y', 'z'], 5);

console.log(obj);

答案 1 :(得分:1)

您可以通过使用数组归约函数来实现:

const objProps = ["a","b","c"]
const value = 5
const newObj = objProps.reverse().reduce((result, curProp)=> (
{
    [curProp]: result
  }
), value)

console.log(newObj)

这将从objProps中的最后一个值开始将prop彼此“链接”。因为要使用名称作为索引,所以使用对象而不是数组。

编辑:好的,所以我再次阅读了您的问题,据我了解,您不想创建新对象,而是通过定义路径来修改大对象内部的值。为此,请看lodash。该库具有方法set,您可以在其中提供指向属性位置的路径并设置新值(https://lodash.com/docs/4.17.11#set)。

答案 2 :(得分:1)

let obj = {
  a: {
    b: {
      c: 'hey',
    }
  }
}

let objProps = ["a", "b", "c"];

function findValue(obj, objProps, index = 0) {
  if (index > objProps.length-1) return obj;
return findValue(obj[objProps[index]],objProps, index+1)
}

findValue(obj, objProps)
let obj = {
  a: {
    b: {
      c: 'hey',
    }
  }
}

let objProps = ["a", "b", "c"];

function assignValue(obj, objProps, newValue, index = 0) {
  console.log(obj)
  if (index >= objProps.length-1 && obj[objProps[index]]) {
    return obj[objProps[index]] = newValue;
    } else {

return assignValue(obj[objProps[index]],objProps, newValue, index+1)
  }
}

assignValue(obj, objProps, "asdsa")

答案 3 :(得分:0)

我精心设计了一个快速解决方案,如果您向我们展示了实际价值,我敢肯定您可以将其与eval一起使用,我可以尝试并为此发布解决方案

但是对于这种黑客攻击:

let objProps = ['a', 'b', 'c'];
let value = ?;
let tmp;
let result = objProps.reduce((acc, curr) => {
    let tmp_v2 = acc;
    while (Object.keys(tmp).length > 0) {
        tmp_v2 = tmp[Object.keys(tmp_v2)[0]]
    }
    tmp_v2[curr] = {};
    tmp = tmp_v2;
    return acc
}, {})
tmp.c = value;

现在result看起来像:

{
  "a": {
    "b": {
      "c": value
    }
  }
}

根据需要。