不能正向双重for+splice去重,因为splice删除元素后数组长度和索引前移,导致内层循环跳过紧邻的下一个元素;正确做法是内层倒序遍历或删除后j--补偿索引。

JavaScript 中用双重 for 循环配合 splice 实现数组去重,本质是**边遍历边删除重复项**,但需特别注意 splice 会改变原数组长度和索引,直接正向遍历时容易跳过元素。正确做法是**倒序遍历内层循环**,或在删除后手动调整索引。
为什么不能正向双重 for + splice?
假设数组 [1, 2, 2, 3, 2],外层 i=1(值为2),内层 j 从 i+1 开始正向遍历:j=2 时发现重复,splice(j, 1) 删除索引2的元素 → 数组变为 [1, 2, 3, 2],原索引3、4的元素前移;但 j 接着自增为3,就跳过了新位置上的 2(原索引4,现索引3)。
安全写法:外层正向,内层倒序遍历
内层从数组末尾向前比对,删除时不影响尚未检查的前面索引:
function uniqueWithSplice(arr) {
// 复制一份避免修改原数组(可选)
const res = [...arr];
for (let i = 0; i i; j--) {
if (res[j] === res[i]) {
res.splice(j, 1); // 删除重复项,不干扰 i 和 j>i 的未检部分
}
}
}
return res;
}
<p>// 示例
console.log(uniqueWithSplice([1, 2, 2, 3, 2, 4, 1])); // [1, 2, 3, 4]
</p>替代思路:只删后续重复,保持首次出现项
更符合“去重保留第一个”的直觉,逻辑清晰,不易出错:
- 外层 i 控制“基准元素”(从头到尾)
- 内层 j 从
i + 1开始正向扫描,但每次splice后让j--补回索引偏移
function uniqueKeepFirst(arr) {
const res = [...arr];
for (let i = 0; i 注意事项与对比
-
性能差:双重循环 +
splice是 O(n³) 级别(splice删除中间元素平均需移动一半元素),仅适合小数据量教学演示 - 仅适用于全等比较(===):无法处理对象、NaN 等特殊情况(NaN !== NaN)
-
推荐生产环境用 Set:
[...new Set(arr)]简洁高效;如需兼容旧浏览器,可用哈希表(Object 或 Map)辅助标记
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











