JavaScript用for循环+if实现数组去重 代码失效原因求解
问题描述
我目前正在学习JavaScript,想要练习for循环与if语句的使用,因此找了一道小练习:移除数组内的所有重复元素。我知道该需求存在更优的实现方案,但我想了解自己编写的代码为何无法正常运行。
问题代码如下:
var arr = [1, 1, 2, 3, 3, 3, 4, 5, 5]; var b = 0; function arrRemover() { for (i = 0; i < arr.length; i++) { b++ if (arr[b] == arr[b + 1]) { arr.splice[b + 1]; } } return arr; } console.log(arrRemover());
代码错误点说明
- 变量声明不规范:
for循环内的i未通过var/let声明,会泄露为全局变量,引发作用域异常;全局变量b不会随着函数调用重置,多次执行函数时b会在上次运行结果的基础上继续自增,直接导致索引越界,访问到undefined。 - 计数逻辑冗余混乱:同时使用循环变量
i和额外变量b做索引同步自增没有必要,且b初始值为0,第一次循环就自增为1,直接跳过数组第一个元素的比对。 splice语法使用错误:splice是数组原型上的方法,调用必须使用小括号(),代码中写的方括号[]是属性访问语法,根本不会触发删除操作。splice传参不符合要求:splice执行删除操作需要传入两个核心参数:删除起始位置的索引、需要删除的元素个数,代码中只传入了一个索引值,就算修正调用语法,也无法完成指定位置的元素删除。- 遍历逻辑存在漏洞:使用
splice删除元素时数组的length会实时变小,原循环固定自增索引的写法,很容易跳过待比对元素,或者触发索引越界。
修正代码(仅使用for循环+if语句,符合练习目标)
如果你的测试用例是排序后重复元素相邻的数组,可以从后往前遍历,删除重复项时不会影响前面未遍历元素的索引,逻辑更简单:
var arr = [1, 1, 2, 3, 3, 3, 4, 5, 5]; function arrRemover() { for (let i = arr.length - 1; i > 0; i--) { if (arr[i] === arr[i - 1]) { arr.splice(i, 1); } } return arr; } console.log(arrRemover()); // 输出结果:[1, 2, 3, 4, 5]
如果要适配无序数组的去重需求,且不修改原数组,可以用两层for循环+if判断实现,不需要借助其他内置API:
var arr = [1, 1, 2, 3, 3, 3, 4, 5, 5]; function arrRemover() { const uniqueArr = []; for (let i = 0; i < arr.length; i++) { let hasDuplicate = false; // 遍历已存的去重结果,检查当前元素是否已存在 for (let j = 0; j < uniqueArr.length; j++) { if (arr[i] === uniqueArr[j]) { hasDuplicate = true; break; } } if (!hasDuplicate) { uniqueArr.push(arr[i]); } } return uniqueArr; } console.log(arrRemover());
内容的提问来源于stack exchange,提问作者Niklas
相关产品推荐
相关产品推荐

