-1

I have

let mydata = { 
  section_a: { 
     color: "red", 
     shape: "cube"
  },
  section_b: {
     length: 34
  }
}

Now I want to write a function that'll insert a new key/value at a path that is dynamic and can change from call to call.

let path = "section_b.go.real.deep";
let newKey = "age";
let newVal = 50;

so that mydata becomes:

 { 
      section_a: { 
         color: "red", 
         shape: "cube"
      },
      section_b: {
         length: 34,
          go: {
             real: {
                deep: {
                   age: 50
                }
             }
          }
      }
    }

Is there any technique to allow something like that? creation of a deep element, along with any potential dynamic hierarchy?

JasonGenX
  • 4,952
  • 27
  • 106
  • 198
  • Does this answer your question? [Accessing nested JavaScript objects with string key](https://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key) – ASDFGerte Jan 15 '20 at 19:05
  • Note: The above link discusses mostly accessing the properties, but modifying them to set is either very simple, or a related counterpart already exists (e.g. discussed is lodash's `_.get`, but you just want lodash's `_.set`). Also note, that there are links in that topic, to even more similar topics, that discuss this in a lot of detail. – ASDFGerte Jan 15 '20 at 19:06

2 Answers2

2

Maybe you're looking for something like this:

let mydata = { 
  section_a: { 
     color: "red", 
     shape: "cube"
  },
  section_b: {
     length: 34
  }
};

let path = "section_b.go.real.deep";
let newKey = "age";
let newVal = 50;

var items = path.split(".");

var item = mydata;

for (var prop of items) {
  if (!item[prop]) {
    item[prop] = {};
  }
  
  item = item[prop];
};

item[newKey] = newVal;

console.log(mydata);
Tân
  • 1
  • 15
  • 56
  • 102
  • strange, it works here, but this code copied elsewhere doesn't work. https://repl.it/repls/ScarceJampackedMacroinstruction any idea why? – JasonGenX Jan 15 '20 at 19:22
  • 1
    @JasonGenX it works, just the `console.log` make it shorter in output, note the `real: [Object]` – BladeMight Jan 15 '20 at 19:30
2

Here's a one-liner:

let mydata = { 
  section_a: { 
     color: "red", 
     shape: "cube"
  },
  section_b: {
     length: 34
  }
};

let path = "section_b.go.real.deep";
let newKey = "age";
let newVal = 50;

path.split(".").reduce((obj,key) => obj[key] || (obj[key] = {}), mydata)[newKey] = newVal;

console.log(mydata);
Klaycon
  • 10,599
  • 18
  • 35