JavaScript使用splice方法实现数组去重仍残留重复值的问题
双重循环搭配splice去重失效的核心原因
- 循环边界提前固化:函数启动时就把数组的初始长度存入
length变量,这个值是静态的,不会随着splice的删除操作同步更新,循环判断的边界和数组实际长度始终存在偏差。 - 正序遍历的索引偏移漏洞:内层循环正序扫描时,一旦在j位置匹配到重复值执行
splice(j,1),原本j位置后方的所有元素会整体向前移位补位。但删除完成后j会直接自增到j+1,恰好跳过了刚移位到j位置的元素,直接造成漏判漏删。 - 拿测试用例
[1,2,2,2,2,2,2]跑一遍实际流程就很清楚:i=1时对应的匹配值是2,第一次删掉j=2位置的重复2后,数组收缩为[1,2,2,2,2,2],此时j直接跳到3,完全跳过了现在位于j=2位置的重复2,最终自然会残留一个没清掉的重复项。
可正常运行的修正实现
调整两个核心逻辑:取消提前固化的长度变量,让循环边界实时匹配数组动态长度;把内层循环改成倒序遍历,避免索引偏移带来的漏判:
var removeDuplicates = function(nums) { for(let i = 0; i < nums.length; i++) { // 从数组末尾反向遍历到i的下一个位置 for(let j = nums.length - 1; j > i; j--) { if(nums[i] === nums[j]) { nums.splice(j, 1) } } } return nums; };
原理解释:倒序扫描时,删除靠后位置的元素不会改变前面未检查元素的索引位置,不会出现刚删完下一轮就跳过检查的问题;同时循环全程读取数组的实时长度,不会拿着初始值卡边界,删多少个元素都不会出现循环次数和数组状态不匹配的问题。
内容的提问来源于stack exchange,提问作者prmdpsn56
相关产品推荐
相关产品推荐

