You need to enable JavaScript to run this app. JS使用splice遍历解析后JSON数组为何出现隔项删除异常
优惠活动
大模型
产品
解决方案
定价
更多

JS使用splice遍历解析后JSON数组为何出现隔项删除异常

数组按规则删除条目出现隔项失效问题

问题复现场景

  • 输入待处理的已解析JSON数组结构:
[
  {
    "idArticle": "1",
    "language": "SK"
  },
  {
    "idArticle": "2",
    "language": "SK"
  },
  {
    "idArticle": "3",
    "language": "SK"
  },
  {
    "idArticle": "4",
    "language": "SK"
  }
]
  • 触发条件:设置 let lang = "x",按照业务逻辑规则,应当保留 language 字段值等于 lang 转大写结果的条目,删除不匹配项。由于所有条目的 language 值为 SK,不等于转换后的 X,预期结果为清空整个数组。
  • 实际运行异常:仅删除 idArticle 为 1、3 的条目,最终保留 id 为 2、4 的两个条目,与预期完全不符。

存在缺陷的问题代码:

function cutArticleList(data) {
    for (i in data) {
        if (data[i].language === lang.toUpperCase()) {
            continue;
        } else {
            data.splice(i, 1);
        }
    }
    res.send(data);
}

问题根因

隔项删除的效果是两个问题叠加导致的:

  1. 正向遍历+就地splice删除的索引位移冲突:data.splice(i, 1) 会直接修改原数组,删除当前索引位置的元素后,原本排在 i+1 位置的元素会向前移动一位,占据当前 i 的位置。此时循环继续按原有步长递增索引,会直接跳过这个刚前移的元素,转而处理 i+2 位置的内容,自然形成删一个漏一个的隔项效果。
    结合本次场景的实际执行流程:
    • 第1轮循环i=0,删除索引0处id为1的条目,原数组变为 [id2, id3, id4],原id3元素移动到索引1的位置
    • 第2轮循环i=1,处理当前索引1处的id3条目,将其删除,原数组变为 [id2, id4],原id4元素移动到索引1的位置
    • 循环结束,最终保留位置在索引0、2的id2、id4,和实际运行结果完全匹配
  2. for...in遍历数组的设计缺陷:for...in 本质是遍历对象的可枚举属性,并非为数组有序遍历设计,在原数组被动态修改时,更容易出现索引错位的问题。

修复参考方案

  • 采用反向遍历方式删除元素:从数组最后一个索引向前遍历,此时删除当前索引位置的元素,不会影响前方尚未遍历元素的索引位置,从根源避免漏检。
  • 使用数组原生 filter() 方法生成符合规则的新数组返回,不直接修改原数组,规避动态索引变化的问题。
  • 正向遍历场景下,执行 splice 删除操作后,手动将当前索引值减1,抵消删除操作带来的位移影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 02:48:02