【问题标题】:Understanding nested for loops in javascript理解 javascript 中的嵌套 for 循环
【发布时间】:2016-07-24 14:45:19
【问题描述】:

我目前正在 freecodecamp 上学习 JavaScript,他们在其中一项练习中有一个嵌套 for 循环的示例:

 var arr = [[1,2], [3,4], [5,6]];
 for (var i=0; i < arr.length; i++) {
  for (var j=0; j < arr[i].length; j++) {
    console.log(arr[i][j]);
  }
}

使用 console.log = 1 2 3 4 5 6 未定义。

我或多或少地了解 for 循环,并且我了解 [i] 和 [j] 用于访问数组(我认为?)。我只是不明白为什么最后它只打印出这些数字?我发现几年前有人问过这个问题,但它只是解释了如何编写它们,而不是它们如何工作:

For loop in multidimensional javascript array

我把它分解成:

var arr = [  [1,2], [3,4], [5,6]];for (var i=0; i < arr.length; i++) {
 console.log(arr[i]);}

打印出来的

[ 1, 2 ]
[ 3, 4 ]
[ 5, 6 ]
undefined

var arr = [  [1,2], [3,4], [5,6]];
for (var i=0; i < arr.length; i++) {  
 for (var j=0; j < arr[i].length; j++) {    
  console.log(arr[i]);  }}

打印出来的:

[ 1, 2 ]
[ 1, 2 ]
[ 3, 4 ]
[ 3, 4 ]
[ 5, 6 ]
[ 5, 6 ]
undefined

var arr = [  [1,2], [3,4], [5,6]];
 for (var i=0; i < arr.length; i++) {  
  for (var j=0; j < arr[i].length; j++) {    
   console.log(arr[j]);  }}

打印出来

[ 1, 2 ]
[ 3, 4 ]
[ 1, 2 ]
[ 3, 4 ]
[ 1, 2 ]
[ 3, 4 ]
undefined

我理解前两个 arr[i]。循环遍历数组并打印出单个元素(在本例中为数组),在第二个中我猜它只执行了两次,因为有两个循环。我不明白的是:

  1. 为什么没有打印出 arr[j] 中的最后一个数组( [5, 6] 去?)
  2. 为什么 arr[i][j] 突然消除了数组而只是 打印出数字
  3. “未定义”的来源

谁能帮我解决这个问题并解释代码在控制台中打印之前所采取的步骤?我真的很想理解它,但我什至不知道如何以正确的方式搜索这个问题。

【问题讨论】:

  • 别担心最后的undefined;这是console.log() 解释代码的副产品。
  • 那是不正确的。 stellatores 在最后得到一个未定义的原因是因为他在最后一个 for 循环中增加 i 在它到达 j 循环之前以达到条件。 For 循环将始终运行一次,并且仅在满足条件时停止。在这种情况下,最后一个循环将 i 推入等于 7,并且数字数组中没有第 7 个位置。这导致未定义,因为数组位置根本没有分配给它的数字。
  • @Korgrue 不,Pointy 是对的。 i 循环在终止之前仅从 0 运行到 2。 undefinedfor 语句的返回值。 console.log('Hi') 做同样的事情:它输出 'Hi' 然后未定义。
  • 在这里我认为这与代码有关。谢谢

标签: javascript for-loop


【解决方案1】:
var arr = [[1,2], [3,4], [5,6]];

这是一个数组数组。像这样阅读会更容易一些:

var arr = [
            [1,2],
            [3,4],
            [5,6]
          ];

这使您更容易看到您有一个包含 3 个数组的数组。外部“for”将遍历每个第一级数组。因此,当 i=0 时,第一个外部 for 循环将获取第一个内部数组 [1,2]:

for (var i=0; i < arr.length; i++) {
    //First time through i=0 so arr[i]=[1,2];
}

在内部循环中,您将一次遍历 3 个内部数组中的每一个。

for (var j=0; j < arr[i].length; j++) {
    //Handle inner array.
}

这个参数获取内部数组的长度:

arr[i].length

因此,在您第一次通过外部循环时,i=0 和 arr[i] 将等于 [1,2],因为您正在抓取第 0 个元素。请记住,数组元素始终从 0 开始计数,而不是 1。

最后你打印出结果:

console.log(arr[i][j]);

第一次通过你可以把它分解一点。 i=0 和 j=0。 arr[0][0] 翻译为从外部数组中获取第一个元素,然后从第一个内部数组中获取第一个元素。在这种情况下,它是“1”:

[
    [1,2], <-- 0
    [3,4], <-- 1
    [5,6]  <-- 2
];

代码将遍历第一个集合 [1,2],然后是第二个 [3,4],依此类推。

【讨论】:

  • 知道了,所以使用 arr[i][j] 你实际上首先获取内部数组,然后获取内部数组中的元素并将其打印出来,谢谢!你的 array[0][0] 让它点击了。并且 console.log(arr[j]) 实际上并没有打印出最后一个内部数组,因为它依赖于 arr[i] ,它们是长度为 2 的内部数组,因此计数器在第三个数组之前停止。非常感谢!
【解决方案2】:

上面的双 for 循环是这样工作的:

 var arr = [[1,2], [3,4], [5,6]];

 for (var i=0; i < arr.length; i++) {
  // i = 0, then we loop below:
  for (var j=0; j < arr[i].length; j++) {
    //here we loop through the array which is in the main array
    //in the first case, i = 0, j = 1, then we loop again, i = 0, j = 1
    console.log(arr[i][j]);
    //after we finish the stuff in the 'j' loop we go back to the 'i' loop 
    //and here i = 1, then we go down again, i, remains at 1, and j = 0, then j = 1
    //....rinse and repeat, 
  }
}

简单的英语:

我们抓取主数组中的第一个元素,它本身就是一个数组, 我们循环遍历它,并在每个索引处记录,这由我们在第二个循环中的长度条件终止。然后我们移动到主数组的下一个索引,这是一个数组本身......等等,直到我们到达主数组的末尾

要在主数组中访问和索引,我们需要使用array[i] - 该索引包含一个数组 - 所以要进入该数组,我们需要使用array[i][j]

希望这是有道理的!

【讨论】:

    【解决方案3】:

    尽管有一些 caveats 在数组上使用 for-in 循环,但它们有时可以帮助清除嵌套循环中的混乱:

    var arr = [[1,2], [3,4],[5,6]];
    
    for (i in arr){
          for (j in arr[i]){
            console.log(arr[i][j]);
          }
        }

    还有code visualization可以澄清执行!

    【讨论】:

      【解决方案4】:

      我知道这是一个老问题...但是因为这是来自 ye olde google search 的热门帖子,我觉得添加一种方法来可视化嵌套 for-循环。

      作为一名 JS 老师,我发现这种方法对视觉导向的人和那些有阅读​​障碍和相关问题的人非常有帮助)。

      // Original: https://repl.it/@justsml/nested-loop-visualizations
      var nums = [[1,2,3], [4,5,6], [7,8,9]];
      
      console.log('Example w/ Numbers:\n');
      console.log('The array data: ', JSON.stringify(nums));
      
      for (var i=0; i < nums.length; i++) {
        // Main/"top" array - accessing via "arr[i]"
        for (var j=0; j < nums[i].length; j++) {
          // here we loop through the "child" arrays
          let helpfulLabel = `nums[${i}][${j}]`
          let value = nums[i][j]
          console.log(helpfulLabel, 'Value=' + value);
        }
      }
      
      console.log('\nExample w/ String Data:\n');
      var letters = [['a', 'b', 'c'], ['d', 'e', 'f'], ['x', 'y', 'z']];
      console.log('The array data: ', JSON.stringify(letters));
      
      for (var i=0; i < letters.length; i++) {
        for (var j=0; j < letters[i].length; j++) {
          let helpfulLabel = `letters[${i}][${j}]`
          let value = letters[i][j]
          console.log(helpfulLabel, 'Value=' + value);
        }
      }

      结果预览

      【讨论】:

        【解决方案5】:
        function multiplyAll(arr) {
           var product = 1;
           // Only change code below this line
           for (var i = 0; i < arr.length; i++) {
             for (var j = 0; j < arr[i].length; j++) {
               product *= arr[i][j];
               console.log(product)
             }
           }
           // Only change code above this line
           return product;
         }
         // Modify values below to test your code
         multiplyAll([[1], [2], [3]])
         //multiplyAll([[1, 2], [3, 4], [5, 6, 7]]);
         //multiplyAll([[5, 1], [0.2, 4, 0.5], [3, 9]])
        

        【讨论】:

          【解决方案6】:
          1. 为什么没有打印出 arr[j] 中的最后一个数组([5, 6] 去吗?)

          您可能会注意到,如果您将j 打印为console.log(j),它将 打印 6 次为0, 1, 0, 1, 0, 1。以及您要打印的内容 是arr[j],其中[5, 6] 不会显示,因为它打开 arr[2]

          1. 为什么 arr[i][j] 突然消除了数组,只打印出数字

          正如你所说,arr 是一个由 3 个数组组成的数组。 arr[i] 代表 [1, 2][3, 4][5, 6] 中的 3 个数组。还有j arr[i][j] 代表这 3 个数组的索引。这就是所谓的 Multidimensional Arrayarr[i][j] 不会消除数组,而是选择arr[i] 内的j 索引中的值。

          1. “未定义”的来源

          当您使用 console.log 时,它只是 chrome 的东西。铬回归 每当您尝试这样做时未定义。尝试在firefox上做,你 再也看不到了。

          【讨论】:

            【解决方案7】:
            function multiply(arr) {
                var product = 1;
            
                for (var i = 0; i < arr.length; i++) {
                    for (var j = 0; j < arr[i].length; j++) {
                        product *= arr[i][j];
                    }
                }
            
                return product;
            }
            

            【讨论】:

            • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation 将通过展示为什么这是解决问题的好方法,并使其对有其他类似问题的未来读者更有用,从而大大提高其长期价值。请edit您的回答添加一些解释,包括您所做的假设。
            猜你喜欢
            • 2022-01-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-07
            • 2021-06-03
            • 1970-01-01
            • 2021-10-23
            相关资源
            最近更新 更多