【问题标题】:For loop not iterating through whole array (Javascript)For循环不遍历整个数组(Javascript)
【发布时间】:2021-09-30 13:42:54
【问题描述】:

我正在尝试解决一个问题,该问题需要一个数组并将所有零移动到末尾,同时保留其他元素的顺序。

这不是遍历整个数组,任何关于我做错了什么的想法将不胜感激。

let moveZeros = function (arr) {
  let newArr = [];
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === 0) {
      newArr.push(arr[i]);
      arr.splice(i, 1);
    }
  }
  return arr.concat(newArr);
};

moveZeros([9, 0, 9, 1, 2, 1, 1, 3, 1, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0]);

// expexted to return [9,9,1,2,1,1,3,1,9,9,0,0,0,0,0,0,0,0,0,0]
// currently returns  [9,9,1,2,1,1,3,1,9,0,9,0,0,0,0,0,0,0,0,0]

// Strangely... sending a smaller array to the function seems to work.

//moveZeros([false,1,0,1,2,0,1,3,"a"])
// correctly returns[false,1,1,2,1,3,"a",0,0]

【问题讨论】:

  • 你知道arr.splice 从数组中删除元素,对吧?所以,for 循环中的i++ 可能会让你跳过一个元素
  • 尝试arr.splice(i--, 1); - “较短”输入似乎起作用的原因是您的“较短”输入从不连续有 2 个零
  • 很好的例子说明为什么在循环遍历数组时更改数组的长度可能不是最好的主意。
  • 尝试找到一个失败的例子并开始调试。

标签: javascript algorithm sorting for-loop iteration


【解决方案1】:

这个问题与长度无关,当你有多个连续的0时会发生。例如[0,0,9,0,0,9]会出现[0,9,0,9 ,0,0]。

在循环的第一次迭代 (i=0) 中,您从数组中删除第一个 0,留下 [0,9,0,0,9]。在第二次迭代 (i=1) 中,它现在查看数组中的第二个元素,即 9。第一个 0 被跳过。随着循环的进行,这也会在数组的后面发生。

通常,在循环遍历数组时修改数组可能会出现问题。有很多方法可以执行这样的排序。但要使其接近您的原件,您可以这样做:

let moveZeros = function(arr) {
    let arrA = [];
    let arrB = [];
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] === 0) {
            arrB.push(arr[i]);
        } else {
            arrA.push(arr[i]);
        }
    }
    return arrA.concat(arrB);
};

现在函数在通过它时保持原始数组的完整性。非 0 项被推送到 arrA,0 被推送到 arrB,然后将这两者连接起来。

【讨论】:

  • 感谢 Josh 的描述,很高兴知道我会记住这一点,以备将来使用。做得很好,这么快就解决了!
【解决方案2】:

您可以过滤和连接数组

let moveZeros = function (arr) {
  let newArr = arr.filter(f => f !== 0)
  let zeroArray = fillArray(0, arr.length - newArr.length)
  return newArr.concat(zeroArray)
};
function fillArray(value, len) {
  let arr = [];
  for (var i = 0; i < len; i++) {
    arr.push(value);
  }
  return arr;
}
let res = moveZeros([9, 0, 9, 1, 2, 1, 1, 3, 1, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0]);
console.log(res)

【讨论】:

    【解决方案3】:

    您可以保留数组并将所有非零值移到开头,然后用零填充其余部分。

    let moveZeros = function(array) {
            let i = 0,
                j = 0;
    
            while (i < array.length) {
                if (array[i] !== 0) array[j++] = array[i];
                i++;
            }
    
            while (j < array.length) array[j++] = 0;
    
            return array;
        };
    
    console.log(...moveZeros([9, 0, 9, 1, 2, 1, 1, 3, 1, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0]));
    console.log(...moveZeros([false, 1, 0, 1, 2, 0, 1, 3, "a"]));

    【讨论】:

      猜你喜欢
      • 2017-05-14
      • 2016-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-18
      相关资源
      最近更新 更多