让我们说我有这个对象:
var obj = {
level1 :{
level2: {
level3: {
title: "winner"
}
}
}
}
现在,我想使用下一个字符串更新title
键(注意,我有一个字符串,而不是实际变量)
我有:
let myString = "level1.level2.level3.title"; // note - myString value comes from $http method or something
也许是这样的:
obj[myString] = "super-winner";
不幸的是,以上操作无效。
此外-有时我需要更新一个未定义的对象,因此我需要一些东西来使要使用新的空对象定义的对象。
例如,如果我有下一个对象:
var obj = {
level1 : {}
}
}
我仍然想用上述的level3.winner来修改obj
。
提醒:
obj[myString] = "super-winner";
我该怎么做?
答案 0 :(得分:1)
这有效
const obj = {
// level1: {
// level2: {
// level3: {
// title: "winner"
// }
// }
// }
}
const myString = "level1.level2.level3.title"; // note - myString value comes from $http method or something
const title = 'super-winner'
myString.split('.')
.reduce(
(acc, curr) => {
if (acc[curr] === undefined && curr !== 'title') {
acc[curr] = {}
}
if (curr === 'title') {
acc[curr] = title
}
return acc[curr]
}, obj
);
console.log(obj) // {"level1":{"level2":{"level3":{"title":"super-winner"}}}}
这是一种零依赖解决方案,即您不必使用lodash或使应用程序规模变大的东西。
答案 1 :(得分:1)
使用“ reduce”来获得所需的结果。创建了一个函数“ updateValue”,您可以在其中传递obj-要修改的对象,str-要更改的属性路径,value-要在属性路径处分配的值
var obj1 = {
level1 :{
level2: {
level3: {
title: "winner"
}
}
}
}
var obj2 = { level1: {} }
var obj3 = {
level1 :{
level2: {
level3: {
title: "winner"
}
}
}
}
function updateValue(obj, str, value) {
let props = str.split('.'), arrIndex = -1
props.reduce((o,d,i) => (
arrIndex = d.indexOf('[') > -1 && d[d.indexOf('[') + 1],
arrIndex && (d = d.slice(0, d.indexOf('['))),
i == props.length - 1
? o[d] = value
: (o[d] = o[d] || {}, (arrIndex && (Array.isArray(o[d]) || (o[d] = [o[d]]))), arrIndex && o[d][arrIndex] || o[d])
)
, obj)
}
updateValue(obj1, 'level1.level2.level3.title', 'abcd')
updateValue(obj2, 'level1.level2.level3.title', 'abcd')
updateValue(obj3, 'level1.level2[0].title', 'abcd')
console.log(obj1)
console.log(obj2)
console.log(obj3)
答案 2 :(得分:0)
您可以使用.set
https://lodash.com/docs#set
lodash
功能
例如:_.set(obj, 'level1.level2.level3.title', 'super-winner');
或使用ES6语法功能:
var str = 'level1.level2.level3.title';
str.split('.').reduce((p, c, index) => {
if (index === str.split('.').length - 1) {
if (typeof p[c] !== "object") { // string, number, boolean, null, undefined
p[c] = 'super-winner'
}
return p[c];
} else {
if (!p[c] || typeof p[c] !== 'object') {
p[c] = {};
}
return p[c];
}
}, obj)
console.log(obj);
答案 3 :(得分:0)
这可以手动完成,反复索引到对象结构中,并根据需要在到达目标键的路径上创建新对象:
const updateField = (o, path, entry) => {
path = path.split(".");
let curr = o;
while (path.length > 1) {
const dir = path.shift();
const parent = curr;
curr = curr[dir];
if (undefined === curr) {
parent[dir] = {};
curr = parent[dir];
}
}
if (path.length === 1) {
curr[path.shift()] = entry;
}
return o;
};
var obj = {
level1 : {
level2: {
level3: {
title: "winner"
}
}
}
};
console.log(JSON.stringify(updateField(obj, "level1.level2.level3.title", "super-winner"), null, 2));
console.log(JSON.stringify(updateField({}, "level1.level2.level3.title", "super-winner"), null, 2));