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

如何高效按name键对嵌套数组内compensatedItems分组统计

JavaScript 嵌套数组按name字段分组计数高效实现

核心思路是用哈希表做分组存储,实现线性时间复杂度O(k)(k为所有compensatedItems下元素的总个数),没有冗余遍历,是该场景下的理论最优方案。


最优实现代码(普通对象版,性能最佳)

适合绝大多数场景,无原型对象的属性查找速度最快,无额外依赖:

const groupItems = (sourceArr) => {
  // 创建无原型纯净对象作为哈希表,避免原型链属性冲突,提升查找速度
  const groupMap = Object.create(null);
  for (const parent of sourceArr) {
    // 兼容边界情况:compensatedItems不存在或不是数组时跳过
    if (!Array.isArray(parent.compensatedItems)) continue;
    for (const item of parent.compensatedItems) {
      const itemName = item.name;
      if (groupMap[itemName]) {
        // 已存在同名分组,直接累加计数
        groupMap[itemName].count += 1;
      } else {
        // 新分组,拷贝原条目属性,初始化count为1
        groupMap[itemName] = { ...item, count: 1 };
      }
    }
  }
  // 哈希表的值转为数组即为最终结果
  return Object.values(groupMap);
};

// 调用即可得到你需要的结果
const res = groupItems(arr);

ES6 Map 版本

如果存在name为非字符串类型(比如Symbol、数字类型的key)的场景,可以用Map替代纯净对象,性能和前者基本持平:

const groupItems = (sourceArr) => {
  const groupMap = new Map();
  for (const parent of sourceArr) {
    if (!Array.isArray(parent.compensatedItems)) continue;
    for (const item of parent.compensatedItems) {
      const itemName = item.name;
      if (groupMap.has(itemName)) {
        groupMap.get(itemName).count += 1;
      } else {
        groupMap.set(itemName, { ...item, count: 1 });
      }
    }
  }
  return Array.from(groupMap.values());
};

性能注意事项

  • 避免使用Array.find在结果数组里查找匹配分组的写法,这种写法每处理一个元素都要遍历一次结果数组,时间复杂度会退化为O(n²),数据量超过1000条后性能会明显下降,示例如下(不推荐):

❌ 低性能反例

// 数据量大时请勿使用
const badResult = arr
  .flatMap(i => i.compensatedItems)
  .reduce((acc, cur) => {
    const exist = acc.find(i => i.name === cur.name);
    exist ? exist.count++ : acc.push({...cur, count: 1});
    return acc;
  }, []);
  • 以上给出的实现默认相同name的条目,id、reason等其他属性值完全一致,和你提供的示例场景匹配。如果存在同name但其他属性不同的需求,可以按需调整合并逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 09:15:39