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

JavaScript遍历数组并移零至末尾:现有代码未完成遍历的问题

问题分析与修复

原代码的问题

  • 循环条件错误:i <= arr.length会触发数组越界访问(数组最大索引为arr.length - 1),当i等于数组长度时,arr[i]为undefined,后续交换操作逻辑混乱。
  • 交换逻辑缺陷:遇到0仅与下一个元素交换,还错误地将下一个元素设为字符串"0";若交换后当前位置仍为0(比如连续0的场景),i++会直接跳过该位置,导致部分0无法被移动到末尾。

修复方案

方案1:双指针原地修改(高效无额外数组)

用两个指针分别标记非0元素的插入位置和遍历位置,先把所有非0元素移到数组前半段,再将剩余位置填充为0。

function moveZeros(arr) {
  let nonZeroIndex = 0;
  // 移动非0元素到前面
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] !== 0) {
      arr[nonZeroIndex] = arr[i];
      nonZeroIndex++;
    }
  }
  // 填充剩余位置为0
  for (let i = nonZeroIndex; i < arr.length; i++) {
    arr[i] = 0;
  }
  return arr.join(', ');
}
console.log(moveZeros([1,2,0,1,0,1,0,3,0,1]));
// 输出:1, 2, 1, 1, 3, 1, 0, 0, 0, 0

方案2:过滤重组(简洁直观)

先过滤出所有非0元素,再补充对应数量的0,最后拼接成目标格式的字符串。

function moveZeros(arr) {
  const nonZeros = arr.filter(item => item !== 0);
  const zeros = Array(arr.length - nonZeros.length).fill(0);
  return [...nonZeros, ...zeros].join(', ');
}
console.log(moveZeros([1,2,0,1,0,1,0,3,0,1]));
// 输出:1, 2, 1, 1, 3, 1, 0, 0, 0, 0

方案3:基于交换思路优化

如果想保留原有的交换逻辑,需要调整循环条件和索引递增规则,遇到0时不直接递增索引,直到当前位置非0为止:

function moveZeros(arr) {
  let i = 0;
  // 循环到倒数第二个元素,避免访问i+1越界
  while (i < arr.length - 1) {
    if (arr[i] === 0) {
      // 交换当前元素与下一个元素,使用数字0而非字符串
      [arr[i], arr[i+1]] = [arr[i+1], 0];
      // 交换后当前仍为0则不递增索引,继续处理
      if (arr[i] === 0) continue;
    }
    i++;
  }
  return arr.join(', ');
}
console.log(moveZeros([1,2,0,1,0,1,0,3,0,1]));
// 输出:1, 2, 1, 1, 3, 1, 0, 0, 0, 0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 22:50:22