JavaScript数组移除连续重复元素的最优实现方案
移除数组连续重复元素的高效实现
假设你有这样一个数组:
[1, 1, 2, 2, 1, 2, 2, 2]
需要移除其中连续重复的元素(非全局去重),最终得到没有元素紧跟自身重复的结果,比如上面的示例预期输出是:
[1, 2, 1, 2]
目前已经有两种实现方式,这里聊聊哪种更高效,以及有没有更简洁的写法。
现有实现方案
1. for循环实现
const arr = [1, 1, 2, 2, 1, 2, 2, 2]; const result = [arr[0]]; let lastElement = arr[0]; for (let i = 1, n = arr.length; i < n; ++i) { if (arr[i] !== lastElement) { lastElement = arr[i]; result.push(lastElement); } }
2. filter方法实现
const result = [1, 1, 2, 2, 1, 2, 2, 2].filter((element, index, arr) => element !== arr[index - 1]);
关于简洁性
filter的写法已经足够简洁,一行代码就能完成需求,逻辑清晰易懂。如果非要追求极致短的代码,可以简写变量名,但可读性会打折扣,比如:
const result = arr.filter((e,i,a)=>e!==a[i-1])
但一般不推荐这种简写,原filter写法已经平衡了简洁性和可读性。
关于执行效率
for循环的执行效率更高,原因很直接:
for循环是直接对数组进行遍历操作,没有额外的函数调用开销,每一步判断和push都是原生操作,减少了回调函数调用带来的栈开销和上下文切换。filter方法虽然简洁,但本质上会为数组的每个元素调用一次回调函数,这种函数调用的额外损耗在处理超大数组时会被放大,效率不如for循环。
另外,原for循环实现有个小问题:如果数组是空的,arr[0]会是undefined,导致结果数组里多一个无效值。可以优化成下面这样,兼容空数组的情况:
const arr = [1, 1, 2, 2, 1, 2, 2, 2]; const result = []; let lastElement; for (let i = 0, n = arr.length; i < n; ++i) { if (arr[i] !== lastElement) { lastElement = arr[i]; result.push(lastElement); } }
而filter方法天然支持空数组,空数组调用filter后还是空数组,不需要额外处理边界情况。
总结
- 想要代码简洁易读:选
filter方法,写法清爽,逻辑直观。 - 追求最高执行效率:选
for循环,尤其是处理大规模数据时,性能优势更明显。
内容的提问来源于stack exchange,提问作者Thorben Croisé
相关产品推荐
相关产品推荐

