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

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

Setting n-th subobject based on array of keys

问题

我有一个名为pivot的对象,它具有不同深度的多个访问器。

对于键数组const keys = ['rotation'],我希望我的代码像这样分配值x

  1. pivot['rotation'] = x

对于数组const keys = ['rotation', 'y'],我希望代码执行以下操作:

  1. pivot['rotation']['y'] = x

我尝试的解决方案如下:

  1. accessors.forEach(a => accessor = accessor[a])
  2. accessor = x

然而,在记录accessor值之后,我发现它只是一个原始值0.1,而不是一个对象引用。

我能以某种方式获得对象引用吗?或者我需要采用不同的方法来实现这一点?

可行的代码可能看起来像下面这个丑陋的示例,但这是不可接受的。

  1. if (accessors.length == 1) {
  2. pivot[accessors[0]] = x
  3. } else if (accessors.length == 2) {
  4. pivot[accessors[0]][accessors[1]] = x
  5. }
英文:

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:

  1. pivot['rotation'] = x

And for array const keys = ['rotation', 'y'] I want the code to do this:

  1. pivot['rotation']['y'] = x

Solution I tried looks like this:

  1. accessors.forEach(a => accessor = accessor[a])
  2. 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.

  1. if (accessors.length == 1) {
  2. pivot[accessors[0]] = x
  3. } else if (accessors.length == 2) {
  4. pivot[accessors[0]][accessors[1]] = x
  5. }

答案1

得分: 2

You could reduce the array of keys and preserve the last key as an accessor for assigning the value.

  1. const
  2. setValue = (reference, keys, value) => {
  3. const last = keys.pop();
  4. keys.reduce((o, k) => o[k] ??= {}, reference)[last] = value;
  5. },
  6. pivot = {};
  7. setValue(pivot, ['rotation', 'x'], 'y');
  8. 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 = {};

  1. setValue(pivot, [&#39;rotation&#39;, &#39;x&#39;], &#39;y&#39;);
  2. console.log(pivot);

<!-- end snippet -->

答案2

得分: 2

这是类似于lodash的set的东西。请记住这会改变对象。

  1. const pivot = {}
  2. const set = (obj, path, value) => {
  3. const pathLength = path.length;
  4. path.reduce((acc, key, i) => {
  5. if (acc[key] === undefined) acc[key] = {}
  6. if (i === pathLength - 1) acc[key] = value
  7. return acc[key]
  8. }, obj)
  9. }
  10. set(pivot, ['rotation', 'x'], 'y');
  11. 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 -->

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

  1. const pivot = {}
  2. const set = (obj, path, value) =&gt; {
  3. const pathLength = path.length;
  4. path.reduce((acc, key, i) =&gt; {
  5. if (acc[key] === undefined) acc[key] = {}
  6. if (i === pathLength - 1) acc[key] = value
  7. return acc[key]
  8. }, obj)
  9. }
  10. set(pivot, [&#39;rotation&#39;, &#39;x&#39;], &#39;y&#39;);
  11. console.log(pivot);

<!-- end snippet -->

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

在Nunjucks模板中访问数组在 :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定