I have nested objects, for example:
var a = {b: {c: {d: 1}}};
and a dynamic key:
var field = "b.c.d"
I need to change a value at object a
by key bcd
. Nesting level of object and key can vary. The only thing which works for me is:
eval("a."+field+"=2"); -> it means a.b.c.d = 2;
But it's ugly. Is there a better way?
You can try following using a recursive function
var a = {b: {c: {d: 1}}}; var field = "bcd"; var value = 2; function updateObject(obj, key, val){ if(obj) { if(key.includes(".")) { var keys = key.split("."); updateObject(obj[keys.shift()], keys.join("."), val); } else if (obj.hasOwnProperty(key)) obj[key] = val; } } updateObject(a, field, value); console.log(a);
You can simply use a recursive function to update the value:
var a = {b: {c: {d: 1}}}; function updateValue(obj, path,value){ if(typeof path == "string") path = path.split("."); if(path.length == 1) obj[path[0]] = value; else updateValue(obj[path[0]], path.slice(1), value); } updateValue(a, "bcd", 2); console.log(a);
Here is another solution, in case you have to use the same path several times and want to create a function you can use to set the value:
var a = {b: {c: {d: 1}}}; function createSetter(path) { return path.split(".") .reverse() .reduce((setter, key) => (setter ? (o,value) => setter(o[key],value) : (o,value) => o[key]=value ), null) } var myBCDSetter = createSetter("bcd") myBCDSetter(a,2) console.log(a) myBCDSetter(a,3) console.log(a)
You can use lodash _.set(object, path, value)
. In your case _.set(a, "bcd", 2)
Refer to docs here
You could use Function constructor, it works with arrays too:
Object.prototype.modify = function (path,value){
let a = Function("object","path","value","object"+path+"=value");
a(this,path,value)
}
var a = {b: {c: {d: 1}}};
var b = {b: {c: {d: [1,[10,20,30],3,4,5]}}};
a.modify(".b.c.d", 3)//<-- change value
b.modify(".b.c.d[1][0]", "new Value")//<-- change value
console.log(a)
console.log(b.b.c)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.