基于键数组设置第 n 个子对象

huangapple go评论61阅读模式
英文:

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, [&#39;rotation&#39;, &#39;x&#39;], &#39;y&#39;);

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) =&gt; {
  // Regex explained: https://regexr.com/58j0k
  const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g)
  const pathLength = pathArray.length;
  pathArray.reduce((acc, key, i) =&gt; {
    if (acc[key] === undefined) acc[key] = {}
    if (i === pathLength - 1) acc[key] = value
    return acc[key]
  }, obj)
}
set(pivot, [&#39;rotation&#39;, &#39;x&#39;], &#39;y&#39;);

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) =&gt; {
  const pathLength = path.length;
  path.reduce((acc, key, i) =&gt; {
    if (acc[key] === undefined) acc[key] = {}
    if (i === pathLength - 1) acc[key] = value
    return acc[key]
  }, obj)
}

set(pivot, [&#39;rotation&#39;, &#39;x&#39;], &#39;y&#39;);

console.log(pivot);

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年4月16日 23:12:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76028574.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定