
本文介绍一种时间复杂度为 O(n) 的方法,通过 filter() 配合索引比较,精准去除数组中连续重复出现的相邻项,保留首次出现的元素,不改变非相邻重复元素的原始顺序。
本文介绍一种时间复杂度为 o(n) 的方法,通过 `filter()` 配合索引比较,精准去除数组中**连续重复出现的相邻项**,保留首次出现的元素,不改变非相邻重复元素的原始顺序。
在实际开发中,我们常需对数组做去重处理,但需注意:全局去重(如 new Set)会破坏原始顺序并抹除所有重复值;而本场景的目标是仅压缩相邻重复项(run-length compression)——即若相同元素连续出现多次,只保留第一个,跳过其后紧邻的重复项。
最简洁高效的实现方式是使用 Array.prototype.filter(),结合当前元素与前一项的比较:
const items = [1, 2, 2, 3, 3, 1, 1, 4, 5, 5, 4, 4, 4, 6, 2]; const result = items.filter((value, index) => value !== items[index - 1]); console.log(result); // [1, 2, 3, 1, 4, 5, 4, 6, 2]
原理说明:
- index - 1 对应前一个元素的索引;
- 当 index === 0 时,items[-1] 为 undefined,value !== undefined 恒为 true,因此首项必然被保留;
- 对后续每一项,仅当它不等于前一项时才被保留,从而自然跳过所有紧邻重复项。
✅ 优势:
- 时间复杂度严格 O(n),仅遍历一次;
- 空间复杂度 O(1)(不计输出数组);
- 无副作用,纯函数式,兼容任何可比较类型(数字、字符串、布尔值等);
- 代码简短、可读性强,无需额外状态变量或循环。
⚠️ 注意事项:
- 该方法依赖 === 严格相等判断,不适用于含对象或嵌套结构的数组(此时需自定义比较逻辑);
- 若需支持 null/undefined 作为有效元素,请确保业务逻辑允许 value !== items[index - 1] 的语义(因 undefined !== undefined 为 false,故首个 undefined 可被保留,但连续 undefined 会被压缩,符合预期)。
总结:对于“移除相邻重复项”这一高频需求,filter((v, i) => v !== arr[i - 1]) 是兼顾性能、简洁性与可维护性的最优实践。










