原文:Nesting For Loops in JavaScript
如果你在理解 freeCodeCamp 的 for 循环嵌套挑战时遇到困难,不要担心,我们会支持你的。
在这个问题中,你必须完成 multiplyAll()
函数,并接受一个多维数组作为参数。请记住,多维数组,有时也称为二维数组,只是一个数组的数组,例如,[[1,2], [3,4], [5,6]]
。
在右边的编辑器中,multiplyAll()
的定义如下:
function multiplyAll(arr) {
var product = 1;
// 只修改这一行下面的代码
// 只修改这一行上面的代码
return product;
}
multiplyAll([[1,2],[3,4],[5,6,7]]);
你需要完成这个函数,使其将 product
变量乘以参数 arr
的子数组中的每个数字,而参数 arr
是一个多维数组。
有很多不同的方法来解决这个问题,但我们将专注于使用 for
循环的最简单的方法。
设置你的 for 循环
因为 arr
是一个多维数组,你需要两个 for
循环:一个是遍历每个子数组,另一个是遍历每个子数组中的元素。
遍历内部数组
要做到这一点,像你在以前的挑战中所做的那样,设置一个 for
循环。
function multiplyAll(arr) {
let product = 1;
// 只修改这一行下面的代码
for (let i = 0; i < arr.length; i++) {
}
// 只修改这一行上面的代码
return product;
}
multiplyAll([[1,2],[3,4],[5,6,7]]);
请注意,我们在循环中使用 let
而不是 var
来声明 product
。在这个挑战中,你不会注意到这两者之间的区别,但一般来说,只要有可能,使用 ES6 的 const
和 let
是很好的做法。你可以在这篇文章中了解更多原因。
现在将每个子数组打印到控制台:
function multiplyAll(arr) {
let product = 1;
// 只修改这一行下面的代码
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// 只修改这一行上面的代码
return product;
}
multiplyAll([[1,2],[3,4],[5,6,7]]);
因为你在用下面的 [[1,2],[3,4],[5,6,7]]
调用 multiplyAll()
,你应该看到以下内容:
[ 1, 2 ]
[ 3, 4 ]
[ 5, 6, 7 ]
遍历每个子数组中的元素
现在你需要遍历你刚刚打印到控制台的子数组中的每个数字。
删除 console.log(arr[i]);
,并在你刚才写的那个里面创建一个 for
循环。
function multiplyAll(arr) {
let product = 1;
// 只修改这一行下面的代码
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i].length; j++) {
}
}
// 只修改这一行上面的代码
return product;
}
multiplyAll([[1,2],[3,4],[5,6,7]]);
记住,对于里面的循环,我们需要检查 arr[i]
的 .length
,因为 arr[i]
是我们前面看的子数组之一。
现在将 arr[i][j]
打印到控制台,以查看每个元素:
function multiplyAll(arr) {
let product = 1;
// 只修改这一行下面的代码
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i].length; j++) {
console.log(arr[i][j]);
}
}
// 只修改这一行下面的代码
return product;
}
multiplyAll([[1,2],[3,4],[5,6,7]]);
1
2
3
4
5
6
7
Finally, multiply product
by every element in each of the sub-arrays:
function multiplyAll(arr) {
let product = 1;
// 只修改这一行下面的代码
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i].length; j++) {
product *= arr[i][j];
}
}
// 只修改这一行上面的代码
return product;
}
multiplyAll([[1,2],[3,4],[5,6,7]]);
如果你把 product
打印到控制台,你会看到每个测试案例的正确答案:
function multiplyAll(arr) {
let product = 1;
// Only change code below this line
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i].length; j++) {
product *= arr[i][j];
}
}
// Only change code above this line
console.log(product);
return product;
}
multiplyAll([[1,2],[3,4],[5,6,7]]);
6 // [[1], [2], [3]]
5040 // [[1, 2], [3, 4], [5, 6, 7]]
54 // [[5, 1], [0.2, 4, 0.5], [3, 9]]
仔细观察
如果你仍然不确定为什么应该写上面的代码,不要担心——你并不孤单。嵌套循环的工作很复杂,即使是有经验的开发者也会感到困惑。
在这样的情况下,在控制台打印一些更详细的内容可能会有帮助。回到你的代码中,打印 `Sub-array ${i}: ${arr[i]}`
到控制台,就在内部 for
循环之前:
function multiplyAll(arr) {
let product = 1;
// 只修改这一行下面的代码
for (let i = 0; i < arr.length; i++) {
console.log(`Sub-array ${i}: ${arr[i]}`);
for (let j = 0; j < arr[i].length; j++) {
product *= arr[i][j];
}
}
// 只修改这一行上面的代码
return product;
}
multiplyAll([[1,2],[3,4],[5,6,7]]);
在外层 for
循环中,每次迭代都要遍历 arr
中的子数组。你应该在控制台中看到这个:
Sub-array 0: 1,2
Sub-array 1: 3,4
Sub-array 2: 5,6,7
注意,我们在上面使用了模板字面量。`Sub-array ${i}: ${arr[i]}`
与 'Sub-array ' + i + ': ' + arr[i]
相同,只是写起来更容易。
现在在内部 for
循环中,打印 `Element ${j}: ${arr[i][j]}`
到控制台:
function multiplyAll(arr) {
let product = 1;
// 只修改这一行下面的代码
for (let i = 0; i < arr.length; i++) {
console.log(`Sub-array ${i}: ${arr[i]}`);
for (let j = 0; j < arr[i].length; j++) {
console.log(`Element ${j}: ${arr[i][j]}`);
product *= arr[i][j];
}
}
// 只修改这一行上面的代码
return product;
}
multiplyAll([[1,2],[3,4],[5,6,7]]);
内层 for
循环会遍历每个子数组(arr[i]
)中的每个元素,所以你应该在控制台看到这个:
Sub-array 0: 1,2
Element 0: 1
Element 1: 2
Sub-array 1: 3,4
Element 0: 3
Element 1: 4
Sub-array 2: 5,6,7
Element 0: 5
Element 1: 6
Element 2: 7
i
的第一次迭代抓取第一个子数组,[1, 2]
。然后,j
的第一次迭代会遍历该子数组中的每个元素:
// i is 0
arr[0] // [1, 2];
// j is 0
arr[0][0] // 1
// j is 1
arr[0][1] // 2
-----
// i is 1
arr[1] // [3, 4]
// j is 0
arr[1][0] // 3
// j is 1
arr[1][1] // 4
...
这个例子相当简单,但是如果不向控制台打印多个元素,还是很难理解 arr[i][j]
。
我们可以做的一个快速改进是在外层 for
循环中声明一个 subArray
变量,并将其设置为等于 arr[i]
:
function multiplyAll(arr) {
let product = 1;
// 只修改这一行下面的代码
for (let i = 0; i < arr.length; i++) {
const subArray = arr[i];
for (let j = 0; j < arr[i].length; j++) {
product *= arr[i][j];
}
}
// 只修改这一行下面的代码
return product;
}
multiplyAll([[1,2],[3,4],[5,6,7]]);
然后只要对代码做一些调整,使用新的 subArray
变量而不是 arr[i]
:
function multiplyAll(arr) {
let product = 1;
// 只修改这一行下面的代码
for (let i = 0; i < arr.length; i++) {
const subArray = arr[i];
for (let j = 0; j < subArray.length; j++) {
product *= subArray[j];
}
}
// 只修改这一行上面的代码
return product;
}
multiplyAll([[1,2],[3,4],[5,6,7]]);
这应该是你需要知道的关于多维数组和 for
循环嵌套的一切。