array.filter((item, index) => array.indexOf(item) === index 工作原理及应用疑问
代码工作原理与需求实现详解
一、array.filter((item, index) => array.indexOf(item) === index) 工作逻辑
首先明确:filter确实会遍历数组所有的(item, index)对,index是filter回调的标准参数,代表当前遍历元素在原数组中的位置索引。
这段代码的核心逻辑是保留数组中每个元素的第一次出现,过滤掉后续重复的元素,拆解来看:
array.indexOf(item):返回当前元素item在原数组中第一次出现的索引(不管后面有没有重复,只找第一个匹配的位置)。- 当
array.indexOf(item) === index时,说明当前遍历到的这个元素,就是它在数组里的首次出现位置——如果元素之前已经出现过,indexOf返回的会是更早的索引,和当前index不相等,就会被filter过滤掉。
举两个实际例子:
数组
[1,1,2]的遍历过程:- 第1个元素(
item=1,index=0):indexOf(1)=0,等式成立,保留 - 第2个元素(
item=1,index=1):indexOf(1)=0,等式不成立,过滤 - 第3个元素(
item=2,index=2):indexOf(2)=2,等式成立,保留 - 最终返回结果:
[1,2]
- 第1个元素(
数组
[1,2,3,2,1]的遍历过程:- 第1个元素(
item=1,index=0):indexOf(1)=0,保留 - 第2个元素(
item=2,index=1):indexOf(2)=1,保留 - 第3个元素(
item=3,index=2):indexOf(3)=2,保留 - 第4个元素(
item=2,index=3):indexOf(2)=1≠3,过滤 - 第5个元素(
item=1,index=4):indexOf(1)=0≠4,过滤 - 最终返回结果:
[1,2,3]
- 第1个元素(
二、找数组中「唯一不重复」元素的实现
上面的代码是去重(保留首次出现),如果你的需求是找整个数组里只出现过一次的元素(比如[1,1,2]里的2,[1,2,3,2,1]里的3),可以用以下两种方式:
方式1:用filter嵌套统计次数(小数据量够用)
// 得到所有只出现一次的元素,取第一个就是目标值 const uniqueItem = array.filter(item => array.filter(i => i === item).length === 1)[0];
逻辑:对每个元素,统计它在数组中的总出现次数,只保留次数为1的元素,最后取结果数组的第一个元素(适用于你给出的只有一个唯一元素的场景)。
方式2:用Map统计次数(大数据量更高效)
const countMap = new Map(); // 先遍历数组统计每个元素的出现次数 array.forEach(item => { countMap.set(item, (countMap.get(item) || 0) + 1); }); // 从Map中找出次数为1的元素 const uniqueItem = [...countMap.keys()].find(key => countMap.get(key) === 1);
逻辑:先通过一次遍历统计所有元素的出现次数,再从Map中筛选出次数为1的元素,时间复杂度是O(n),比方式1的O(n²)更适合处理大数组。
内容的提问来源于stack exchange,提问作者mathsnerd22
相关产品推荐
相关产品推荐

