问题描述
我有JSON对象
var a = { a: { b: 10,c: 10 } }
我想要一个可以动态更改JSON对象的方法。假设当我向方法提供object,string和一个值时,它应该返回更新的JSON对象
change(a,'a.b',30)
更改方法如下:-
function change(obj,str,val) {
const newObject = str.split('.').reverse()
.reduce((a,p,i) => {
if(i===0) a[p] = val
else { let b = {}; b[p] = a; a = b}
return a;
},{})
return { ...obj,...newObject }
}
它应该返回
{ a: { b : 30,c: 10 } }
不修改其他json字段,但当前正在返回
{ a: { b : 30 } }
解决方法
这是一种实现方法:
var a = { a: { b: 10,c: 10 } };
var b = { a: { b: { c: 10 } } };
function change(obj,str,val) {
// get parts of the string as an array
const prop = str.split('.');
// deep clone the object (so you don't modify the original 'a' object,insted you get a new one returned)
const newObj = {...obj};
// save a reference to the new object
let target = newObj;
prop.forEach((el,i) => {
if(i < prop.length-1) {
// replace the reference for a nested reference
target = target[el];
} else {
// if it's the last 'prop' item,change the value
target[el] = val;
}
});
// return the new object
return newObj;
}
console.log(change(a,'a.b',30));
console.log(change(b,'a.b.c',50));
,
您的return语句将用{b:30}覆盖键{b:10,c:10}的值,您得到的是,您可以使用lodash库的set函数执行相同的操作您正在尝试达到
您可以使用以下代码更改值
var a = { a: { b: 10,c: 10 } }
function getObj(obj,key) {
return obj[key];
}
function change(obj,keys,value) {
let newObj = JSON.parse(JSON.stringify(obj));
let str = keys.split('.');
str.reduce( (acc,curr,index) => {
if(index === str.length -1) {
acc[curr]= value;
return acc
}else {
return getObj(acc,curr);
}
},newObj );
return newObj;
}
console.log(change(a,30))
console.log(change(a,'a.c',20))