因为我要处理一个相对较大的对象,所以我希望能够通过定义“路径”来动态修改我的对象值。
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
,但它说“作业中的左侧无效”。
答案 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
}
}
}
根据需要。