【问题标题】:Javascript For don´t complete array loopJavascript For不完成数组循环
【发布时间】:2018-11-24 16:14:31
【问题描述】:

我正在尝试构建一个包含 12 个位置的数组的循环,用 5 个项目包装并在此间隔之后插入另一个代码,但由于某种原因,循环最多只能达到 10 个。 为什么只有当数组有 11 个或 12 个位置时,循环才会在第十个位置停止? 有人可以解释一下原因吗?

let x = [0,1,2,3,4,5,6,7,8,9,10,11];
x.map(_=> {
    console.log("<div>");
    x.splice(0,5).map((y,k)=>
        console.log('item: ' + y)
    )
    console.log("</div>");
    console.log('interval of 5 text');
});

x = [0,1,2,3,4,5,6,7,8,9,10,11];
for(i=0; i < x.length; i++){
    let x2 = x.splice(0,5);
    console.log("<div>");
    for(j=0; j < x2.length; j++){
        console.log('item: ' + x2[j]);
    }
    console.log("</div>");
    console.log('interval of 5');
}

【问题讨论】:

  • 在循环中更改循环中的数组绝不是一个好主意
  • 如果理论上我可以控制它,为什么不呢?无论如何,我只是想了解为什么只有当数组有 11 个或 12 个位置时,循环才会在第十个位置停止?
  • 因为你在循环中改变了数组

标签: javascript arrays for-loop foreach array.prototype.map


【解决方案1】:

这是因为您在迭代时更改了原始数组:

let x2 = x.splice(0,5); // should be avoided.

随着每次更改,数组的长度也会减少。

【讨论】:

    【解决方案2】:

    使用 Array.slice(...) 代替 Array.splice(...)

    let x = [0,1,2,3,4,5,6,7,8,9,10,11]
    
    After a = **x.splice(0,5)** =>
     x => [5,6,7,8,9,10,11]
     a => [0,1,2,3,4]
    
    After a = **x.slice(0,5)** =>
     x => [0,1,2,3,4,5,6,7,8,9,10,11]
     a => [0,1,2,3,4]
    

    由于您使用 ( ... i splice 操作,您将到达数组的末尾。 (使用循环你会得到相同的情况)

    【讨论】:

      【解决方案3】:

      回答你的问题为什么。

      让我稍微澄清一下这个循环,只保留splice 方法(因为它会改变你的数组)并在每次迭代中将数组x 的长度记录到控制台。

      x = [0,1,2,3,4,5,6,7,8,9,10,11];
      for(var i=0; i < x.length; i++){
          let x2 = x.splice(0,5);
          console.log(x.length);
      }

      让我们看看会发生什么。

      loop execution:
      ------------------------------ 
      i  |  x.length  |  i < x.length
      ------------------------------
      0  |     12     |     true
      1  |     7      |     true
      2  |     2      |     false
      

      这就是为什么您的循环在第二次迭代后结束(这是第 10 个位置,因为您在一次迭代中处理了 5 个位置)。


      让代码执行上述逻辑并在之后清除数组的一种方法是这样。

      创建一个执行以下操作的函数:

      • 取组的数组和大小
      • 创建该数组的副本
      • 获得正确的迭代次数
      • 执行你的逻辑
      • 返回(空数组)并重新分配旧数组

      要获得正确的迭代次数,请将数组的长度除以组的大小并向上取整。

      let x = [0,1,2,3,4,5,6,7,8,9,10,11];
      
      function customArrayLoop(arr, toTake) {
        const arrCopy = [...arr];
        const loopMax = Math.ceil(x.length / toTake);
      
        for (let i = 0; i < loopMax; i++) {
          let x2 = arrCopy.splice(0,5);
          console.log("<div>");
          for(let j=0; j < x2.length; j++){
            console.log('item: ' + x2[j]);
          }
          console.log("</div>");
          console.log('interval of 5');
        }
      
        return arrCopy;
      }
      
      x = customArrayLoop(x, 5);
      console.log(x);

      虽然仍然不是你能得到的最好的(因为你想保持循环的内部逻辑),但它是更安全的解决方案。

      【讨论】:

      • 谢谢!我可能会使用 while(x.length) 代替或映射。
      • @ThiagoMachado 是的,将循环更改为while(x.length &gt; 0) 在这种情况下确实有效,但这绝对是错误的方法。究竟想要达到什么目的? (我相信有更好的解决方案)
      • 我想运行整个数组,就像我在帖子中写的那样,并确保最后清理数组。
      • 谢谢!这让我明白了很多。
      猜你喜欢
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-15
      • 1970-01-01
      • 2020-01-13
      • 1970-01-01
      相关资源
      最近更新 更多