You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS for循环结合splice删除数组奇偶位置元素结果异常排查

问题根因

代码存在两个问题,核心错误是正向遍历数组的同时调用splice()修改原数组,引发索引错位,另有一处变量名笔误。

索引错位的具体执行逻辑

splice()删除元素后,被删位置后方的所有元素会自动前移1位,数组长度同步减1,但循环计数器i依旧按固定步长自增,会直接跳过部分元素的校验。我们以传入"odd"(预期删除原数组索引1、3、5的元素,剩余[90,28,26])为例拆解执行过程:

  • 初始状态:i=0,数组为[90,34,28,19,26,22],i为偶数不触发删除,i自增为1
  • i=1:i为奇数,删除当前索引1的元素34,数组变为[90,28,19,26,22],所有索引大于1的元素全部前移一位,i自增为2
  • i=2:当前数组索引2的元素是原索引3的19,i为偶数不触发删除,i自增为3
  • i=3:i为奇数,删除当前索引3的元素26,数组变为[90,28,19,22],后方元素继续前移,i自增为4
  • 此时数组长度为4,i<array.length的循环条件不成立,遍历结束,最终输出错误结果[90,28,19,22]:本该被删除的19、22因为索引错位跳过了校验,被错误保留。

变量笔误

代码中定义的数组名为myArr,但调用函数时传入的是未定义的arr,如果不是贴代码时的抄写错误,代码运行会直接抛出引用错误。

修复方案

方案1:倒序遍历删除(保留原数组修改逻辑)

从数组末尾向前遍历,删除元素时只会影响已经遍历过的后方元素索引,不会干扰未遍历的前方元素,不会出现错位:

const myArr = [90,34,28,19,26,22];

function deleteData (array, occuranceType){
    for (let i = array.length - 1; i >= 0; i--) {
        const isOddDel = occuranceType === "odd" && i % 2 !== 0;
        const isEvenDel = occuranceType === "even" && i % 2 === 0;
        if (isOddDel || isEvenDel) {
            array.splice(i, 1);
        }
    }
}

deleteData(myArr, "odd");
console.log(myArr); // 输出 [90, 28, 26],符合预期

方案2:filter生成新数组(推荐,无副作用)

不直接修改原数组,通过索引判断过滤出需要保留的元素,逻辑更简洁也不会出现索引问题:

const myArr = [90,34,28,19,26,22];

function deleteData (array, occuranceType){
    return array.filter((_, index) => {
        return occuranceType === "odd" ? index % 2 === 0 : index % 2 !== 0;
    })
}

const result = deleteData(myArr, "odd");
console.log(result); // 输出 [90, 28, 26],符合预期

内容的提问来源于stack exchange,提问作者Juan Yeremia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 05:51:17