Artigo original: Nesting For Loops in JavaScript

Está com problemas para entender o desafio Aninhar laços for do freeCodeCamp? Não se preocupe. Estamos aqui para ajudar.

Neste problema, você precisa completar a função multiplyAll(), que recebe um array multidimensional como argumento. Lembre-se de que arrays multidimensionais, ou, neste caso, um array bidimensional, nada mais é do que um array de arrays, como, por exemplo, [[1,2], [3,4], [5,6]].

No editor à direita no desafio, multiplyAll() é definido da seguinte maneira:

function multiplyAll(arr) {
  let product = 1;
  // Altere apenas o código abaixo desta linha

  // Altere apenas o código acima desta linha
  return product;
}

multiplyAll([[1, 2], [3, 4], [5, 6, 7]]);

Você precisa completar a função de modo que ela multiplique a variável product por cada número nos subarrays do parâmetro arr, que é um array bidimensional.

Existem várias maneiras diferentes de resolver esse problema, mas nosso foco aqui será o método mais simples, usando laços for.

Configurando os laços for

Como arr é um array bidimensional, você precisará de dois laços for: um deles percorrerá o laço para cada subarray, enquanto o outro percorrerá os elementos em cada subarray.

Percorrer os arrays internos

Para fazer isso, configure um laço for do mesmo modo que você já fez em desafios anteriores:

function multiplyAll(arr) {
  let product = 1;
  // Altere apenas o código abaixo desta linha
  for (let i = 0; i < arr.length; i++) {
    
  }
  // Altere apenas o código acima desta linha
  return product;
}

multiplyAll([[1,2],[3,4],[5,6,7]]);

Observe que estamos usando let em vez de var para o laço e para declarar product. Neste desafio, você não perceberá a diferença entre os dois, mas, em geral, é uma boa prática usar as declarações const e let da ES6 sempre que você puder. Leia mais sobre o assunto neste artigo.

Agora, faça um console.log de cada um dos subarrays:

function multiplyAll(arr) {
  let product = 1;
  // Altere apenas o código abaixo desta linha
  for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
  }
  // Altere apenas o código acima desta linha
  return product;
}

multiplyAll([[1,2],[3,4],[5,6,7]]);

Como você está chamando multiplyAll() com [[1,2],[3,4],[5,6,7]] na parte inferior do código, você deverá ver o seguinte:

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

Percorrer os elementos de cada subarray

Agora, você precisa percorrer cada número nos subarrays que você acaba de imprimir no console.

Remova console.log(arr[i]); e crie outro laço for dentro daquele que você acaba de escrever:

function multiplyAll(arr) {
  let product = 1;
  // Altere apenas o código abaixo desta linha
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr[i].length; j++) {
      
    }
  }
  // Altere apenas o código acima desta linha
  return product;
}

multiplyAll([[1,2],[3,4],[5,6,7]]);

Lembre-se de que, para o laço interno, precisamos conferir a .length de arr[i], pois arr[i] é um dos subarrays que examinamos antes.

Agora, faça o console.log de arr[i][j] para ver cada um dos elementos individualmente:

function multiplyAll(arr) {
  let product = 1;
  // Altere apenas o código abaixo desta linha
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr[i].length; j++) {
      console.log(arr[i][j]);
    }
  }
  // Altere apenas o código acima desta linha
  return product;
}

multiplyAll([[1,2],[3,4],[5,6,7]]);
1
2
3
4
5
6
7

Por fim, multiplique product por cada elemento em cada um dos subarrays:

function multiplyAll(arr) {
  let product = 1;
  // Altere apenas o código abaixo desta linha
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr[i].length; j++) {
      product *= arr[i][j];
    }
  }
  // Altere apenas o código acima desta linha
  return product;
}

multiplyAll([[1,2],[3,4],[5,6,7]]);

Se mandar product para console.log, você verá a resposta correta de cada caso de teste:

function multiplyAll(arr) {
  let product = 1;
  // Altere apenas o código abaixo desta linha
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr[i].length; j++) {
      product *= arr[i][j];
    }
  }
  // Altere apenas o código acima desta linha
  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]]

Um olhar mais detalhado

Se você ainda não entendeu bem como funciona esse código, fique tranquilo – você não é o único. Trabalhar com laços aninhados (laços dentro de laços) é complicado, e até mesmo desenvolvedores mais experientes podem se confundir.

Em casos como esse, pode ser útil usar console.log de tudo para obter mais detalhes. Vamos voltar para o código e enviar para console.log `Subarray ${i}: ${arr[i]}` antes do laço for interno:

function multiplyAll(arr) {
  let product = 1;
  // Altere apenas o código abaixo desta linha
  for (let i = 0; i < arr.length; i++) {
    console.log(`Subarray ${i}: ${arr[i]}`);
    for (let j = 0; j < arr[i].length; j++) {
      product *= arr[i][j];
    }
  }
  // Altere apenas o código acima desta linha
  return product;
}

multiplyAll([[1,2],[3,4],[5,6,7]]);

No laço for externo, cada iteração percorre os subarrays de arr. Você deverá ver isso no console:

Subarray 0: 1,2
Subarray 1: 3,4
Subarray 2: 5,6,7

Observe que estamos usando template literals acima. `Subarray ${i}: ${arr[i]}` é o mesmo que 'Subarray ' + i + ': ' + arr[i], apenas muito mais fácil de escrever.

Agora, no laço for interno, envie ao console.log `Elemento ${j}: ${arr[i][j]}`:

function multiplyAll(arr) {
  let product = 1;
  // Altere apenas o código abaixo desta linha
  for (let i = 0; i < arr.length; i++) {
    console.log(`Subarray ${i}: ${arr[i]}`);
    for (let j = 0; j < arr[i].length; j++) {
      console.log(`Elemento ${j}: ${arr[i][j]}`);
      product *= arr[i][j];
    }
  }
  // Altere apenas o código acima desta linha
  return product;
}

multiplyAll([[1,2],[3,4],[5,6,7]]);

O laço for interno percorre cada elemento em cada subarray (arr[i]) e você verá o seguinte no console:

Subarray 0: 1,2
Elemento 0: 1
Elemento 1: 2
Subarray 1: 3,4
Elemento 0: 3
Elemento 1: 4
Subarray 2: 5,6,7
Elemento 0: 5
Elemento 1: 6
Elemento 2: 7

A primeira iteração de i obtém o primeiro subarray, [1, 2]. Então, a primeira iteração de j percorre cada elemento daquele subarray:

// i é 0
arr[0] // [1, 2];

// j é 0
arr[0][0] // 1
// j é 1
arr[0][1] // 2

-----

// i é 1
arr[1] // [3, 4]

// j é 0
arr[1][0] // 3
// j é 1
arr[1][1] // 4

...

Esse é um exemplo bem simples, mas arr[i][j] ainda pode ser difícil de entender sem enviar para console.log diversas informações.

Uma melhoria rápida que podemos fazer é declarar uma variável subArray no laço for externo e defini-la como arr[i]:

function multiplyAll(arr) {
  let product = 1;
  // Altere apenas o código abaixo desta linha
  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];
    }
  }
  // Altere apenas o código acima desta linha
  return product;
}

multiplyAll([[1,2],[3,4],[5,6,7]]);

Em seguida, basta fazer alguns ajustes no código e usar a nova variável subArray em vez de arr[i]:

function multiplyAll(arr) {
  let product = 1;
  // Altere apenas o código abaixo desta linha
  for (let i = 0; i < arr.length; i++) {
    const subArray = arr[i];
    for (let j = 0; j < subArray.length; j++) {
      product *= subArray[j];
    }
  }
  // Altere apenas o código acima desta linha
  return product;
}

multiplyAll([[1,2],[3,4],[5,6,7]]);

Isso deve ser tudo o que você precisa saber sobre arrays multidimensionais e laços for aninhados. Agora, siga em frente e faça seus próprios testes!