TypeScript遍历数组splice删项后push剩余id结果异常如何解决
问题原因
代码无法得到预期结果有两个核心问题:
- 判断条件语法错误:
item.id === z12中的z12未加字符串引号,会被TypeScript解析为变量而非字符串字面量。如果代码中没有提前声明名为z12的变量会直接抛出引用错误;即使声明了变量,也无法和值为字符串类型的"z12"的id匹配。 - 遍历逻辑存在索引错位:
forEach遍历按照初始索引顺序递增执行,遍历过程中调用splice删除原数组元素会触发数组元素前移、长度缩短,后续遍历会直接跳过被删位置后的第一个元素,导致元素漏处理。
执行流程示例(假设判断条件已修正):- 初始数组索引对应关系:0→z12、1→z13、2→z14,遍历按索引0、1、2的顺序执行
- 遍历到index=0时匹配到z12,执行
splice(0,1)删除元素,数组变为[z13,z14],长度缩短为2 - 下一轮遍历index=1,此时新数组索引1对应的元素是z14,位于新数组索引0的z13被直接跳过,既不会被判定删除,也不会被加入结果数组
- 最后一轮遍历index=2,此时数组长度仅为2,无对应元素,遍历结束,最终结果只会得到
["z14"],和预期不符。
修正方法
优先使用无副作用的原生数组方法处理,不要在遍历过程中直接修改原遍历数组,参考实现如下:
const array = [ {id: "z12", val: "lu", val2: "1"}, {id: "z13", val: "la", val2: "2"}, {id: "z14", val: "lo", val2: "3"}, ] const array2: {tab: string[]} = { tab: [], } // 过滤掉id为z12的元素后提取id,直接得到预期结果 array2.tab = array .filter(item => item.id !== "z12") .map(item => item.id) // 如果需要同步删除原数组中的z12项,执行以下逻辑即可 const validItems = array.filter(item => item.id !== "z12") array.length = 0 array.push(...validItems)
如果必须保留遍历+splice的写法,需要改为倒序遍历避免索引错位,同时修正判断条件的字符串引号问题:
for (let i = array.length - 1; i >= 0; i--) { const item = array[i] if (item.id === "z12") { array.splice(i, 1) } else { // 倒序遍历需要用unshift保证顺序和原数组一致 array2.tab.unshift(item.id) } }
内容的提问来源于stack exchange,提问作者static
相关产品推荐
相关产品推荐

