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
相关产品推荐
相关产品推荐

