将具有对象属性的数组分组的最佳方法以及如何呈现结果

Posted

技术标签:

【中文标题】将具有对象属性的数组分组的最佳方法以及如何呈现结果【英文标题】:Best way to group an array with property of object and how to render the result 【发布时间】:2022-01-12 20:11:35 【问题描述】:

我试图找到解决问题的方法,但找不到,所以我有一组对象(产品),每个产品都有一个类别属性,我想按类别对产品进行分组。我设法使用 reduce() 来做到这一点,但现在我需要先呈现类别名称,然后是该类别中的产品。

例子:

const products = [
 id: 1, category: 'Burgers', name: 'Burger',
 id: 2, category: 'Burgers', name: 'Cheeseburger',
 id: 3, category: 'Meals', name: 'Burger meal',
 id: 4, category: 'Meals', name: 'Cheeseburger meal'
]

我需要按类别对这些产品进行分组,我使用 reduce() 做到了这一点

const menu = products.reduce((menu, product) => 
    if (menu[product.category] == null) menu[product.category] = []
    menu[product.category].push(product)
    return menu
, [])

所以现在我的结果是

[Burgers: Array(2), Meals: Array(2)]

但我想用 map() 渲染那些,我该怎么做呢?或者我怎样才能改变结果? 我希望结果是这样的

Categories: [
 
   0: 
   name: 'Burgers',
   products: Array(2)
 ,
 
   1:
   name: 'Meals',
   products: Array(2)
 
]

这样我就可以用类似地图的方式渲染该数组

<div>
  menu.map((c, index) =>
    <Category key=index name=c.name products=c.products />
  )
</div>

【问题讨论】:

【参考方案1】:

const products = [
 id: 1, category: 'Burgers', name: 'Burger',
 id: 2, category: 'Burgers', name: 'Cheeseburger',
 id: 3, category: 'Meals', name: 'Burger meal',
 id: 4, category: 'Meals', name: 'Cheeseburger meal'
]

const menu = products.reduce((acc, product)=> 
    const categoryIndex = acc.findIndex(item => item.name == product.category);
    if(categoryIndex > -1)
        acc[categoryIndex].products.push(product);
    else 
        acc.push( name: product.category, products: [product] )
    ;
    return acc;
, []);

console.log(menu)

【讨论】:

不错。无需解构类别,特别是因为您使用它的属性被命名为 name。我自己也想要这样的方法。我认为我的不太优雅(但我认为在编写时更容易推理) 对,我编辑了代码。【参考方案2】:

起初,我只是回答关于如何分组的纯 javascript 问题

products.reduce((prev, curr) => 
  if(!prev.categories.hasOwnProperty(curr.category)) prev.categories[curr.category] = prev.count++

  const index = prev.categories[curr.category]
  if(!Array.isArray(prev.menu[index])) prev.menu[index] = []

  prev.menu[index].push(curr) 

  return prev
, count: 0, menu: [], categories:).menu

从那里,我猜你的地图应该是这样的:

<div>
  menu.forEach((c, i) =>  
     <Category key=i name=c[0].category products=c />
  )
</div>

【讨论】:

以上是关于将具有对象属性的数组分组的最佳方法以及如何呈现结果的主要内容,如果未能解决你的问题,请参考以下文章

如何按天、周、月对具有时间戳属性的对象进行分组?

优化数据呈现方式,分组双轴图是最佳选择

比较对象数组,最佳方式

对 Prop(来自父级)对象的属性进行计算并将结果放入模板的最佳方法

在 ES6 JS 中“分组”对象数组的最佳方式?

将具有嵌套对象的对象保存到文件的最佳方法?