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

JavaScript for循环中splice删除数组指定元素失效问题

问题原因
  • 核心错误是splice方法调用参数完全不符合语法要求:Array.splice()的第一个参数是数值类型的删除起始索引,第二个参数是数值类型的删除元素个数。你代码里写的department_arr.splice(course, course)传入了两个对象作为参数,JS会将对象隐式转换为数字,最终得到NaN,传入非法索引时splice不会执行任何有效删除,匹配成功的课程项始终留在department_arr数组中。
  • 遍历逻辑没有做命中拦截:for...of循环每次执行时,不管内层if有没有命中匹配,都会走到循环最后一行追加空字段表格行的逻辑,匹配成功的课程自然会同时渲染出带作业数据的行和空字段行。
  • 额外风险:如果后续修正splice参数后,在for...of正向遍历数组的过程中直接splice修改原数组,会导致数组长度变化、元素索引前移,很容易出现漏遍历、重复遍历的问题。
  • 另外你代码中所有表格行都设置了相同的id="accordion",HTML规范要求id在页面中全局唯一,重复id会导致后续DOM操作、事件绑定出现异常。
修复方案

不需要在遍历过程中边遍历边删除数组元素,用匹配标记控制渲染逻辑即可,等全部遍历完成后再统一过滤更新原数组,从根源上避免遍历错乱问题,参考代码如下:

for (let course of department_arr) {
  // 标记当前课程是否匹配到新作业
  let isMatched = false;
  for (let i in new_assignment_ls) {
    if (course.CourseName == new_assignment_ls[i][3] &&
      course.Semester == new_assignment_ls[i][4].split(' ').slice(1).join(' ') &&
      course.Route == new_assignment_ls[i][5].split(' ').slice(1).join(' ')) {

      dataHtml += `<tr class='accordion' onclick="newAssign(this)"><td>${new_assignment_ls[i][0]}</td><td>${new_assignment_ls[i][1]}</td><td>${new_assignment_ls[i][2]}</td><td>${course.Year}</td><td>${course.Semester}</td><td>${course.Route}</td><td>${course.CourseName}</td></tr>`;
      isMatched = true;
      // 匹配到即可终止内层循环,减少不必要的遍历
      break;
    }
  }
  // 仅未匹配到新作业的课程,才渲染空字段行
  if (!isMatched) {
    dataHtml += `<tr class='accordion' onclick="newAssign(this)"><td></td><td></td><td></td><td>${course.Year}</td><td>${course.Semester}</td><td>${course.Route}</td><td>${course.CourseName}</td></tr>`;
  }
}
// 遍历完成后统一过滤掉已匹配作业的课程,更新原数组
department_arr = department_arr.filter(course => {
  return !new_assignment_ls.some(assign => {
    return course.CourseName == assign[3] &&
      course.Semester == assign[4].split(' ').slice(1).join(' ') &&
      course.Route == assign[5].split(' ').slice(1).join(' ')
  })
})

如果你一定要在遍历过程中用splice删除元素,不要用for...of,改用倒序for循环遍历,删除元素不会影响未遍历部分的索引:

// 倒序遍历,从最后一个元素开始遍历
for (let idx = department_arr.length - 1; idx >= 0; idx--) {
  const course = department_arr[idx];
  let isMatched = false;
  for (let i in new_assignment_ls) {
    if (course.CourseName == new_assignment_ls[i][3] &&
      course.Semester == new_assignment_ls[i][4].split(' ').slice(1).join(' ') &&
      course.Route == new_assignment_ls[i][5].split(' ').slice(1).join(' ')) {

      dataHtml += `<tr class='accordion' onclick="newAssign(this)"><td>${new_assignment_ls[i][0]}</td><td>${new_assignment_ls[i][1]}</td><td>${new_assignment_ls[i][2]}</td><td>${course.Year}</td><td>${course.Semester}</td><td>${course.Route}</td><td>${course.CourseName}</td></tr>`;
      isMatched = true;
      break;
    }
  }
  if (isMatched) {
    // 正确传入索引和删除数量,删除当前匹配项
    department_arr.splice(idx, 1);
  } else {
    dataHtml += `<tr class='accordion' onclick="newAssign(this)"><td></td><td></td><td></td><td>${course.Year}</td><td>${course.Semester}</td><td>${course.Route}</td><td>${course.CourseName}</td></tr>`;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 10:51:31