【问题标题】:Flatten array of objects展平对象数组
【发布时间】:2021-12-25 01:45:19
【问题描述】:

我有一个来自 formData serializeArray 函数的对象数组。例如:

[
        0 : {name: 'animal_monkey', value: 'banana'}
        1 : {name: 'animal_horse', value: 'radishes'}
        2 : {name: 'fruit_banana', value: 'yellow'}
        3 : {name: 'fruit_apple', value: 'red'}
]

我正在寻找一种方法将这些不同的元素放入一个对象中,按类别拆分并为其分配适当的值,如下所示:

{ 
        animal: { 
                        monkey : banana,
                        horse : radishes
                },
        fruit: {
                        banana : yellow,
                        apple : red
               }
}

我试过用 reduce 和 Object assign 来做这个,就像这样

obj = keys.map((k, i) => k.reduceRight((value, key) => ({[key]: value}), vals[i]) )
result = Object.assign({}, ...obj)

其中 keys 是 ['animal_monkey', 'animal_horse', 'fruit_banana', 'fruit_apple'] 的数组,而 vals 是一个包含值的列表:['banana', 'radishes', 'yellow', 'red' ]。但是,也许正如预期的那样,这些值被覆盖了,我最终得到:

{ 
        animal: { 
                        horse : radishes
                },
        fruit: {
                        apple : red
               }
}

第一个值在分配中不存在。有谁知道如何完成这项工作?

谢谢!

【问题讨论】:

  • 你能设计一个更好的数据结构吗?例如{ type: 'animal', name: 'monkey', food: 'banana' }。可能会让事情变得更容易。
  • 如果数据中有不止一只猴子,您将面临您想要获得的结构的数据丢失。
  • 谢谢大家;数据中没有其他猴子,所以我不担心数据丢失(我之前遇到过,所以取出了其他猴子)。安迪,你的建议是有道理的,但是数据来自一个 serializeArray 调用,它只给了我表单的名称和值;现在,动物和马被编码为“animal_horse”作为名称,而值是“萝卜”。

标签: javascript arrays javascript-objects


【解决方案1】:

你可以设置一个变量来保存最终的组合对象,然后使用array.forEach为数组中的每个元素添加它

let single = {};
arr.forEach(obj => {
  let [catagory, name] = obj.name.split('_'); // catagory = before the _, name = after the _
  single[catagory] ??= {}; // make sure the catagory exists as an object in single
  single[catagory][name] = obj.value;
}

【讨论】:

  • 也是个好建议!我也要测试这个!谢谢大家!
  • 这也很好用!而且我完全可以看到它是上述答案的一个很好的替代方案,当然区别在于使用 reduce 与 forEach。使用它们有什么缺点吗?例如,forEach 是否比 reduce 更有效?
【解决方案2】:

您可以在_ 上拆分每个name,然后使用array#reduce 创建一个具有类别和动物名称的对象。

const data = [ {name: 'animal_monkey', value: 'banana'}, {name: 'animal_horse', value: 'radishes'}, {name: 'fruit_banana', value: 'yellow'}, {name: 'fruit_apple', value: 'red'} ],
      result = data.reduce((r,o) => {
            const [category, name] = o.name.split('_');
            r[category] ??= {};
            r[category][name] = o.value;
            return r;
      }, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 谢谢!这看起来很有希望——我会在今天晚些时候试一试,让你知道结果如何:)
  • 太棒了!这很好地完成了这项工作。快速提问:我以前使用过 Javascript,但之前没有见过 ??= 运算符;那是新的吗?它有什么作用?此外,我一直在努力理解 reduce。有什么好的建议吗?谢谢!
  • ??nullish coalesing operator。你可以参考 MDN 来了解数组 reduce。
猜你喜欢
  • 2018-02-24
  • 2015-05-23
  • 2023-01-11
  • 2021-12-29
  • 2020-07-04
  • 2017-04-06
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多