【问题标题】:In array of objects group items by common property [duplicate]在对象数组中按公共属性分组项目[重复]
【发布时间】:2021-08-18 18:11:13
【问题描述】:

我有两个大数组,一个是项目,另一个是拥有这些项目的名称。我需要将所有具有匹配项的名称推送到 array2 项中。

我可以通过嵌套 forEach 循环来做到这一点:

array1 = [
  {item: "1", name: "Joe" },
  {item: "2", name: "Sam" },
  {item: "1", name: "Alice"},
  {item: "3", name: "Peter"},
  {item: "1", name: "Jack"},
]

array2 = [
  { item: "1", names: []},
  { item: "2", names: []},
  { item: "3", names: []},
]

array2.forEach(x => {
    array1.forEach(y => {
        if( x.item === y.item ){
        x.names.push(y.name)
        }
    })
})
console.log(array2)

但我感觉这是一种不好的做法,更不用说大型阵列上的资源繁重了。

现代的方法是什么?

【问题讨论】:

  • 请记住,您可能并不总是知道可用的item 值可按它们分组。因此,事情可能会变得更糟,因为您需要遍历源数组以获取唯一的 item 值,从而从中构建您的 array2
  • 为了让您了解与mine 相比,您的解决方案对于 1k 记录可能会有多糟糕的情况,例如,您可以参考此benchmark
  • 我从您的示例和文档链接中学到了很多,欣赏它

标签: javascript html foreach


【解决方案1】:

我相信,您最好利用Map

const src = [
        {item: "1", name: "Joe" },
        {item: "2", name: "Sam" },
        {item: "1", name: "Alice"},
        {item: "3", name: "Peter"},
        {item: "1", name: "Jack"},
      ],
      
      result = [...src
        .reduce((acc, {item,name}) => {
          const group = acc.get(item)
          group
            ? group.names.push(name)
            : acc.set(item, {item, names:[name]})
          return acc
        }, new Map)
        .values()
      ]
      
console.log(result)      

【讨论】:

  • 这工作得很好,而且显然更快,虽然老实说我正在努力理解一些使用的语法:“...”,“?”,“:”,有没有好的来源帮助了解这里发生的事情的文档。
  • @Jeffs:别担心,伙计。 ...简单来说就是一个spread syntax,用来把Map.prototype.values()返回的迭代器转成数组; condition ? then : elseternary operator 并且是 if.. then.. else.. 的简写形式
【解决方案2】:
array2.forEach(a2 => { 
     let names = array1.filter(a1 => a1.item === a2.item)
                       ?.map(n => n.name); 
     a2.names = names ?? []; 
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2014-11-28
    • 1970-01-01
    • 2020-11-12
    • 2021-08-21
    • 1970-01-01
    相关资源
    最近更新 更多