简体   繁体   中英

How to assign a value to nested object by varying key?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM