I have object pivot, that has multiple accessors of different depths.
For keys array const keys = ['rotation'] I want my code to assign value x like this:
pivot['rotation'] = x
And for array const keys = ['rotation', 'y'] I want the code to do this:
pivot['rotation']['y'] = x
Solution I tried looks like this:
accessors.forEach(a => accessor = accessor[a])
accessor = x
However, after logging the accessor value, I found out it’s just primitive value of 0.1, instead of an object reference.
Can I get the object reference somehow? Or do I need to go a different path to achieve this?
Working code would also be something ugly like next example, which is not acceptable.
if (accessors.length == 1) {
pivot[accessors[0]] = x
} else if (accessors.length == 2) {
pivot[accessors[0]][accessors[1]] = x
}
>Solution :
here is something similar to lodash set. keep in mind this mutates the object
const pivot = {}
const set = (obj, path, value) => {
// Regex explained: https://regexr.com/58j0k
const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g)
const pathLength = pathArray.length;
pathArray.reduce((acc, key, i) => {
if (acc[key] === undefined) acc[key] = {}
if (i === pathLength - 1) acc[key] = value
return acc[key]
}, obj)
}
set(pivot, ['rotation', 'x'], 'y');
console.log(pivot);
since your path is already an array you don’t need the regex part
const pivot = {}
const set = (obj, path, value) => {
const pathLength = path.length;
path.reduce((acc, key, i) => {
if (acc[key] === undefined) acc[key] = {}
if (i === pathLength - 1) acc[key] = value
return acc[key]
}, obj)
}
set(pivot, ['rotation', 'x'], 'y');
console.log(pivot);