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

如何用JavaScript的filter替代reduce实现分组?性能孰优?

用Filter实现合并相同Key的数组对象?性能对比分析

一、用Filter实现的写法

Filter本身是用来筛选元素的,要实现合并得搭配其他方法。先拿到所有不重复的stage,再逐个用Filter筛出对应元素,最后提取content:

const data = [{
    "stage": "AT_CALLCENTER",
    "content": "Hello",
  },
  {
    "stage": "AT_CALLCENTER",
    "content": "Bye",
  },
  {
    "stage": "AT_SITE",
    "content": "Good",
  },
  {
    "stage": "AT_SITE",
    "content": "Morning",
  }
];

// 先获取所有唯一的stage值
const uniqueStages = [...new Set(data.map(item => item.stage))];

// 遍历每个stage,用filter筛选对应元素并提取content
const result = {};
uniqueStages.forEach(stage => {
  result[stage] = data.filter(item => item.stage === stage).map(item => item.content);
});

console.log(result);

二、Filter根本不是更优选择

你朋友说Filter性能更好是错的,核心原因是:

  • 遍历次数差太多:Reduce的实现只需要遍历数组1次(时间复杂度O(n));而Filter的方式,每遇到一个新的stage,就要把整个数组再遍历一遍(时间复杂度O(n*m),m是不同stage的数量)。数据量越大,这种重复遍历的性能损耗越夸张。
  • 另外你原来的Reduce代码其实还有优化空间——每次用...展开对象和数组会创建新的引用,没必要。改成直接操作累加器对象,性能会更上一层楼:
// 优化后的Reduce写法,避免不必要的展开操作
const optimizedResult = data.reduce((acc, item) => {
  // 如果当前stage还没在累加器里,先初始化空数组
  if (!acc[item.stage]) {
    acc[item.stage] = [];
  }
  // 直接往数组里push内容,不用创建新数组
  acc[item.stage].push(item.content);
  return acc;
}, {});

这个优化版的Reduce,不仅时间复杂度还是O(n),内存开销也更小,处理大量数据时比Filter的写法快得多,也比你原来的Reduce代码高效。

三、总结

  • Filter能实现需求,但性能拉胯,尤其是数据量大的时候,完全不如Reduce。
  • 最优方案是用优化后的Reduce写法,既简洁又高效,适合生产环境处理大量数据的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:45:51