Reputation: 1145
I am working with a javascript object and need to set a value deep in the object structure.
Lets say:
a.b.c.d.e.f.g = "some value";
I don't know if all of these objects are created yet, so I end up doing:
a = a || {};
a.b = a.b || {};
a.b.c = a.b.c || {};
a.b.c.d = a.b.c.d || {};
a.b.c.d.e = a.b.c.d.e || {};
a.b.c.d.e.f = a.b.c.d.e.f || {};
a.b.c.d.e.f.g = "some value";
Surely there is a better way to do this right?
Upvotes: 0
Views: 54
Reputation: 207531
Easiest way is to use a string, split on the dots, and loop. When you loop you check to see if it exists, if it does, you use it. If it does not than you create a new object. You do that until you get to the end where you set the value.
const setValue = (obj, path, value) => {
path.split('.') // split on the dots
.reduce((o, k, i, a) => {
o[k] = (i + 1 === a.length) // check if we are at last index
? value // if last index use the value
: (o[k] || {}) // else return object or set new one
return o[k] // return the current step in the object
}, obj) // start location
}
setValue(window, 'a.b.c.d.e.f.g', 'some value')
console.log(a.b.c.d.e.f.g)
var foo = { a : { b: {z : {} } } }
setValue(foo, 'a.b.c.d.e.f.g', 'another value')
console.log(foo)
Upvotes: 2
Reputation: 370859
I'd use reduce
to iterate over all props but the last, creating an object at the nested property if necessary, and returning the nested value. Then, on the last object, assign to the last property:
a = window.a || {};
const props = ['b', 'c', 'd', 'e', 'f'];
const lastProp = 'g';
const lastObj = props.reduce((a, prop) => {
if (!a[prop]) a[prop] = {};
return a[prop];
}, a);
lastObj[lastProp] = 'some value';
console.log(a);
Upvotes: 1