过滤重复元素指只保留出现且仅出现一次的元素,可用filter+indexof+lastindexof判断首次与末次位置是否相同;对nan不友好,对象数组需按字段统计频次后筛选。

要过滤掉数组中“所有重复出现过的元素”,意思是:只保留那些**出现且仅出现一次**的元素,把出现两次及以上的全部剔除。这和常见的“去重(保留首次出现)”不同,目标是得到“独一份”的元素。
用 filter + indexOf + lastIndexOf 配合判断
这是最直观、兼容性好、逻辑清晰的方法。核心思路是:对每个元素,检查它在数组中第一次出现的位置和最后一次出现的位置是否相同——只有相同时,才说明它只出现了一次。
-
代码写法:
arr.filter(item => arr.indexOf(item) === arr.lastIndexOf(item)) - 适用于数字、字符串、布尔值等基本类型
- 对
NaN不友好(因为indexOf和lastIndexOf都无法正确识别NaN),如需支持NaN,需额外处理 - 保持原数组顺序,不修改原数组
用 reduce 统计频次再筛选
先遍历统计每个值出现的次数,再过滤出频次为 1 的项。适合需要复用频次信息,或后续可能扩展逻辑的场景。
-
代码示例:
const count = arr.reduce((acc, item) => {<br> acc.set(item, (acc.get(item) || 0) + 1);<br> return acc;<br>}, new Map());<br>const uniqueOnce = arr.filter(item => count.get(item) === 1); - 用
Map而不是普通对象,可安全处理NaN、undefined、对象等各类键 - 性能略低于第一种(需两遍遍历),但语义更明确、扩展性强
针对对象数组:按字段提取唯一出现项
如果数组里是对象,比如 [{id: 1}, {id: 2}, {id: 1}],想筛出 id 只出现一次的对象,不能直接用全等比较,得先提取关键字段做统计。
-
推荐做法:用
Map记录每个id出现次数,再遍历原数组,只保留count.get(obj.id) === 1的对象 - 避免用
JSON.stringify做键——不稳定,且无法处理函数、undefined、循环引用 - 若字段值可能为
null或undefined,注意Map对它们是区分存储的,行为符合预期
注意和常见“去重”的区别
很多人混淆“去重”和“过滤重复项”:
-
去重(如
[...new Set(arr)])→ 结果是[1,2,3](保留首次,合并重复) -
过滤重复项(本文目标)→ 输入
[1,2,2,3,3,4],输出是[1,4](只留出现一次的) - 别误用
filter + indexOf的经典去重写法,它保留的是首次出现项,不是“只出现一次”的项











