英文:
Setting n-th subobject based on array of keys
问题
我有一个名为pivot
的对象,它具有不同深度的多个访问器。
对于键数组const keys = ['rotation']
,我希望我的代码像这样分配值x
:
pivot['rotation'] = x
对于数组const keys = ['rotation', 'y']
,我希望代码执行以下操作:
pivot['rotation']['y'] = x
我尝试的解决方案如下:
accessors.forEach(a => accessor = accessor[a])
accessor = x
然而,在记录accessor
值之后,我发现它只是一个原始值0.1
,而不是一个对象引用。
我能以某种方式获得对象引用吗?或者我需要采用不同的方法来实现这一点?
可行的代码可能看起来像下面这个丑陋的示例,但这是不可接受的。
if (accessors.length == 1) {
pivot[accessors[0]] = x
} else if (accessors.length == 2) {
pivot[accessors[0]][accessors[1]] = x
}
英文:
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
}
答案1
得分: 2
You could reduce the array of keys and preserve the last key as an accessor for assigning the value.
const
setValue = (reference, keys, value) => {
const last = keys.pop();
keys.reduce((o, k) => o[k] ??= {}, reference)[last] = value;
},
pivot = {};
setValue(pivot, ['rotation', 'x'], 'y');
console.log(pivot);
英文:
You couldd reduce the array of keys and preserve the last key as accessor for assigning the value.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const
setValue = (reference, keys, value) => {
const last = keys.pop();
keys.reduce((o, k) => o[k] ??= {}, reference)[last] = value;
},
pivot = {};
setValue(pivot, ['rotation', 'x'], 'y');
console.log(pivot);
<!-- end snippet -->
答案2
得分: 2
这是类似于lodash的set
的东西。请记住这会改变对象。
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);
英文:
here is something similar to lodash set
. keep in mind this mutates the object
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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);
<!-- end snippet -->
since your path is already an array you don't need the regex part
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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);
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论