JavaScript for循环遍历数组splice删除时跳过元素问题
问题根因
跳过元素的核心原因是正向遍历数组过程中调用splice删除元素会触发索引偏移:
- 数组调用
splice删除元素后,被删位置后方的所有元素会自动向前补位,数组长度同步减1 - 但循环索引
i仍会正常自增,会直接跳过补位到当前i位置的元素
对应你代码的异常执行流程:
- 初始数组索引映射:
0:Facebook、1:Google、2:Microsoft、3:Apple、4:IBM、5:Oracle、6:Amazon - 当
i=0时,检测到Facebook含2个'o',执行splice(0,1)删除,此时Google补位到索引0位置,数组长度变为6 - 下一轮循环
i自增为1,直接访问新数组索引1的元素(原索引2的Microsoft),补位到索引0的Google被直接跳过 - 后续
i=2时检测到Microsoft含2个'o'执行删除,Apple补位到索引2位置,下一轮i自增为3,Apple也被跳过,最终输出不符合预期。
修复方法
方法1:倒序遍历(最小改动原逻辑)
从数组末尾向前遍历,删除元素只会影响已经遍历过的后部元素,不会干扰未遍历的前部元素索引,从逻辑上避免跳过问题:
const itCompanies = ['Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon']; // 从最后一个元素开始往前遍历 for (let i = itCompanies.length - 1; i >= 0; i--){ let s = itCompanies[i].split(''); let count = 0; for (let j = 0; j < s.length; j++){ if (s[j] == 'o' ){ count++; } } if (count >= 2){ itCompanies.splice(i, 1); } } console.log(itCompanies); // 输出: ['Apple', 'IBM', 'Oracle', 'Amazon']
方法2:使用filter过滤(更推荐的无副作用写法)
不需要手动修改原数组,直接通过过滤规则生成符合要求的新数组,从根源避免索引偏移问题,代码可读性更高:
const itCompanies = ['Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon']; const filteredCompanies = itCompanies.filter(company => { // 统计字符串中'o'的出现次数 const oCount = (company.match(/o/g) || []).length; return oCount < 2; }) console.log(filteredCompanies); // 输出: ['Apple', 'IBM', 'Oracle', 'Amazon']
注:你标注的预期输出数组长度为5属于笔误,实际符合过滤规则的元素共4个。
内容的提问来源于stack exchange,提问作者Jashuraku
相关产品推荐
相关产品推荐

