You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将对象数组按category和subCategory分组并统计重复项数量?

按分类嵌套分组并统计重复项次数

问题描述

现有如下对象数组:

const data = [
  {labelSlug: 'cola', category: 'catering', subCategory: 'drinks', provider: 'coca cola'},
  {labelSlug: 'cola', category: 'catering', subCategory: 'drinks', provider: 'coca cola'},
  {labelSlug: 'fanta', category: 'catering', subCategory: 'drinks', provider: 'coca cola'},
  {labelSlug: 'activities1', category: 'activities', subCategory: 'activitiesSub1', provider: 'blabla'},
  {labelSlug: 'activities2', category: 'activities', subCategory: 'activitiesSub1', provider: 'blabla'},
  {labelSlug: 'equipments1', category: 'equipments', subCategory: 'equipmentsSub1', provider: 'blabla'},
  {labelSlug: 'equipments2', category: 'equipments', subCategory: 'equipmentsSub2', provider: 'blabla'},
  {labelSlug: 'cola', category: 'catering', subCategory: 'drinks', provider: 'coca cola'},
];

需要将其按category和subCategory嵌套分组,同时统计相同labelSlug和provider组合的出现次数,最终结构如下(注:原示例中数组嵌套键值对存在语法错误,实际应为对象嵌套):

{
  "catering": {
    "drinks": [
      { "labelSlug": "cola", "provider": "coca cola", "count": 3 },
      { "labelSlug": "fanta", "provider": "coca cola", "count": 1 }
    ]
  },
  "activities": {
    "activitiesSub1": [
      { "labelSlug": "activities1", "provider": "blabla", "count": 1 },
      { "labelSlug": "activities2", "provider": "blabla", "count": 1 }
    ]
  },
  "equipments": {
    "equipmentsSub1": [
      { "labelSlug": "equipments1", "provider": "blabla", "count": 1 }
    ],
    "equipmentsSub2": [
      { "labelSlug": "equipments2", "provider": "blabla", "count": 1 }
    ]
  }
}

尝试使用map方法实现但未成功,尝试代码如下:

const array = data.map((elem) => {
  const item = {};
  const sub = elem.subCategory;
  const cat = elem.category;

  // i've tried many things like that just to get everything in the right place (I didnt try to get the count part yet)
  // item[cat[sub]].labelSlug = elem.labelSlug;
  // item[cat][sub].labelSlug = elem.labelSlug;
  // item[cat[sub.labelSlug]] = elem.labelSlug;

  // const item = {
  //   [`${cat}`] : {
  //      [`${sub}`] : {
  //        labelSlug: elem.labelSlug
  //      } 
  //   }
  // }
  return item;
})

解决方案

map方法仅用于转换数组元素,无法实现分组聚合逻辑,应使用reduce方法来完成数据的分组和计数:

const data = [
  {labelSlug: 'cola', category: 'catering', subCategory: 'drinks', provider: 'coca cola'},
  {labelSlug: 'cola', category: 'catering', subCategory: 'drinks', provider: 'coca cola'},
  {labelSlug: 'fanta', category: 'catering', subCategory: 'drinks', provider: 'coca cola'},
  {labelSlug: 'activities1', category: 'activities', subCategory: 'activitiesSub1', provider: 'blabla'},
  {labelSlug: 'activities2', category: 'activities', subCategory: 'activitiesSub1', provider: 'blabla'},
  {labelSlug: 'equipments1', category: 'equipments', subCategory: 'equipmentsSub1', provider: 'blabla'},
  {labelSlug: 'equipments2', category: 'equipments', subCategory: 'equipmentsSub2', provider: 'blabla'},
  {labelSlug: 'cola', category: 'catering', subCategory: 'drinks', provider: 'coca cola'},
];

const groupedData = data.reduce((acc, { labelSlug, category, subCategory, provider }) => {
  // 确保当前分类在累加器中存在,不存在则创建空对象
  if (!acc[category]) {
    acc[category] = {};
  }
  // 确保当前子分类在对应分类下存在,不存在则创建空数组用于存储统计项
  if (!acc[category][subCategory]) {
    acc[category][subCategory] = [];
  }
  // 生成唯一标识,判断是否已存在相同的labelSlug和provider组合
  const uniqueKey = `${labelSlug}-${provider}`;
  // 在子分类数组中查找已有项
  const existingItem = acc[category][subCategory].find(item => `${item.labelSlug}-${item.provider}` === uniqueKey);
  
  if (existingItem) {
    // 已有项则计数加1
    existingItem.count++;
  } else {
    // 无该项则添加新统计项,初始计数为1
    acc[category][subCategory].push({ labelSlug, provider, count: 1 });
  }
  
  return acc;
}, {});

console.log(groupedData);

代码说明

  1. reduce聚合:reduce接收累加器acc和当前遍历元素,逐步构建最终的分组结构。
  2. 层级校验:每次遍历先检查category和subCategory对应的层级是否存在,避免访问未定义属性报错。
  3. 唯一标识匹配:通过labelSlug和provider拼接成唯一键,快速判断是否已统计过该组合。
  4. 计数更新:找到已存在的组合则增加计数,否则添加新项并初始化计数为1。

内容的提问来源于stack exchange,提问作者Kevin Ganem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:10:47