Как присвоить значение вложенному объекту, меняя ключ? - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть вложенные объекты, например:

var a = {b: {c: {d: 1}}};

и динамический ключ:

var field = "b.c.d"

Мне нужно изменить значение в объекте a с помощью ключа b.c.d. Уровень вложенности объекта и ключа может варьироваться. Единственное, что работает для меня:

eval("a."+field+"=2"); -> it means a.b.c.d = 2;

Но это ужасно. Есть ли лучший способ?

Ответы [ 5 ]

0 голосов
/ 13 сентября 2018

Вот еще одно решение, если вам нужно использовать один и тот же путь несколько раз и вы хотите создать функцию, которую вы можете использовать для установки значения:

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("b.c.d")

myBCDSetter(a,2)
console.log(a)

myBCDSetter(a,3)
console.log(a)
0 голосов
/ 12 сентября 2018

Вы можете использовать конструктор функций, он работает и с массивами:

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)
0 голосов
/ 12 сентября 2018

Вы можете просто использовать рекурсивную функцию для обновления значения:

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, "b.c.d", 2);
console.log(a);
0 голосов
/ 12 сентября 2018

Вы можете использовать lodash _.set(object, path, value).В вашем случае _.set(a, "b.c.d", 2)

См. Документы здесь

0 голосов
/ 12 сентября 2018

Вы можете попробовать следовать, используя рекурсивную функцию

var a = {b: {c: {d: 1}}};
var field = "b.c.d";
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);
...