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

如何将给定数组按category属性分组生成新的对象数组?

按category分组数组的实现方案及性能分析

需求说明

给定如下汽车数组:

const CARS = [
  {make: "skoda", model: "kodiaq", color: "light-blue", id: "1002", category: "A"},
  {make: "skoda", model: "karoq", color: "green", id: "1008", category: "B"},
  {make: "renault", model: "clio", color: "grey", id: "1006", category: "A"},
  {make: "renault", model: "kangoo", color: "white", id: "1042", category: "C"},
  {make: "mazda", model: "cx3", color: "red", id: "1022", category: "C"},
  {make: "mazda", model: "cx30", color: "orange", id: "1106", category: "D"},
  {make: "ford", model: "explorer", color: "grey", id: "1162", category: "B"},
  {make: "ford", model: "edge", color: "red", id: "1862", category: "A"}
];

需要将其转换为按category分组的数组,格式如下:

const NEW_CARS = [
  {
    category: "A",
    data: [
      {make: "skoda", model: "kodiaq", color: "light-blue", id: "1002", category: "A"},
      {make: "renault", model: "clio", color: "grey", id: "1006", category: "A"},
      {make: "ford", model: "edge", color: "red", id: "1862", category: "A"}
    ]
  },
  {
    category: "B",
    data: [
      {make: "skoda", model: "karoq", color: "green", id: "1008", category: "B"},
      {make: "ford", model: "explorer", color: "grey", id: "1162", category: "B"}
    ]
  },
  {
    category: "C",
    data: [
      {make: "renault", model: "kangoo", color: "white", id: "1042", category: "C"},
      {make: "mazda", model: "cx3", color: "red", id: "1022", category: "C"}
    ]
  },
  {
    category: "D",
    data: [
      {make: "mazda", model: "cx30", color: "orange", id: "1106", category: "D"}
    ]
  }
];

同时需要考虑大数组场景下的性能最优实现。

实现方案

1. 性能最优方案:对象映射+reduce+Object.values

该方案仅遍历原数组一次,通过对象映射将category作为键,避免重复查找,时间复杂度为O(n),适合大数组场景:

// 第一步:用reduce构建类别映射对象
const groupMap = CARS.reduce((map, car) => {
  const category = car.category;
  // 若当前类别未在映射中,初始化分组对象
  if (!map[category]) {
    map[category] = { category, data: [] };
  }
  // 将当前车辆加入对应分组的data数组
  map[category].data.push(car);
  return map;
}, {});

// 第二步:将映射对象转为目标格式的数组
const NEW_CARS = Object.values(groupMap);

2. 简洁但性能一般的方案:去重类别+map+filter

代码简洁直观,但需多次遍历数组,时间复杂度为O(n*k)(k为类别数量),仅适合小数组或类别极少的场景:

// 提取所有唯一的category
const uniqueCategories = [...new Set(CARS.map(car => car.category))];

// 遍历每个类别,过滤出对应车辆组成分组
const NEW_CARS = uniqueCategories.map(category => ({
  category,
  data: CARS.filter(car => car.category === category)
}));

3. 不推荐的方案:直接reduce+find

每次迭代需遍历累加器数组查找分组,时间复杂度为O(n²),数组越大性能下降越明显:

const NEW_CARS = CARS.reduce((acc, car) => {
  // 查找当前类别已存在的分组
  const existingGroup = acc.find(item => item.category === car.category);
  if (existingGroup) {
    existingGroup.data.push(car);
  } else {
    acc.push({ category: car.category, data: [car] });
  }
  return acc;
}, []);

性能对比

方案时间复杂度适用场景
对象映射+reduce+Object.valuesO(n)大数组、类别数量多的场景
去重类别+map+filterO(n*k)小数组、类别数量极少的场景
直接reduce+findO(n²)无优势,不推荐使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:23:26