reduce适合聚合操作:去重可用数组+includes或set+对象双累加器;统计频次可用对象或map;合并去重与频次时用map记录次数、数组维护顺序,再转为有序对象。

reduce 是一个功能强大的数组方法,适合在一次遍历中完成聚合操作。用它实现数组去重和统计频次,关键在于合理设计累加器(accumulator)的结构——去重常用 Set 或对象/Map 记录已见元素,统计频次则用 对象或 Map 存键值对:元素 → 出现次数。
用 reduce 去重(返回新数组,保持顺序)
核心思路:用空数组作为累加器,每遇到一个没出现过的元素就 push 进去。可用 Set 辅助判断,或直接用 includes(简单数组)。
- 基础写法(适用于简单类型):
const arr = [1, 2, 2, 3, 4, 4, 5];
const unique = arr.reduce((acc, item) => {
if (!acc.includes(item)) acc.push(item);
return acc;
}, []);
// → [1, 2, 3, 4, 5]
- 更高效写法(用 Set 记录已见项,O(1) 查找):
const unique = arr.reduce(
(acc, item) => {
if (!acc.seen.has(item)) {
acc.seen.add(item);
acc.result.push(item);
}
return acc;
},
{ seen: new Set(), result: [] }
).result;
用 reduce 统计频次(返回对象或 Map)
累加器初始化为一个空对象(或 new Map()),遍历中对每个元素做“计数+1”操作。
- 返回普通对象(键为字符串,注意数字/布尔会被转字符串):
const arr = ['a', 'b', 'a', 'c', 'b', 'a'];
const count = arr.reduce((acc, item) => {
acc[item] = (acc[item] || 0) + 1;
return acc;
}, {});
// → { a: 3, b: 2, c: 1 }
- 返回 Map(支持任意类型键,更严谨):
const countMap = arr.reduce((acc, item) => {
acc.set(item, (acc.get(item) || 0) + 1);
return acc;
}, new Map());
// → Map(3) { 'a' → 3, 'b' → 2, 'c' → 1 }
一步到位:去重 + 频次合并(按首次出现顺序返回频次对象)
如果既要唯一性、又要频次、还希望结果保持原始顺序(如按首次出现排),可以把两者结合:
const arr = [2, 1, 2, 3, 1, 2];
const result = arr.reduce(
(acc, item) => {
if (!acc.map.has(item)) {
acc.map.set(item, 1);
acc.order.push(item);
} else {
acc.map.set(item, acc.map.get(item) + 1);
}
return acc;
},
{ map: new Map(), order: [] }
);
// 转成按序对象(可选)
const orderedCount = Object.fromEntries(
result.order.map(key => [key, result.map.get(key)])
);
// → { 2: 3, 1: 2, 3: 1 }
注意事项
- 对象作累加器时,别忘了 return acc,否则下一轮 acc 变成 undefined
- 基本类型(string/number/boolean)可直接作对象键;引用类型(array/object)需转为字符串(如 JSON.stringify)才可用,否则会丢失区分度
- 需要深去重或复杂对象比较时,reduce 不是最佳选择,应配合 Map + 自定义 key 生成,或改用 filter + findIndex 等组合
- 性能上,对于超大数组,Set / Map 的 O(1) 查找比 includes 更稳定;但简单场景下可读性优先
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











