Artigo original escrito por: Sonya Moisset
Artigo original: Three ways you can find the largest number in an array using JavaScript
Traduzido e adaptado por: Daniel Rosa

Neste artigo, explicarei como resolver o desafio Free Code Camp’s "Retornar os maiores números em arrays", do freeCodeCamp. Ele envolve retornar  um array com os maiores números de cada um dos subarrays.

Tratarei aqui de três abordagens:

  1. com um laço FOR
  2. usando o método reduce()
  3. usando Math.max()

A descrição do desafio de algoritmos

Retorne um array que consiste no maior número de cada sub-array fornecido. Por simplicidade, o array fornecido conterá exatamente 4 sub-arrays.

Lembre-se: você pode iterar através de um array com um loop simples, e acesse cada membro com a sintaxe de array arr[i].
function largestOfFour(arr) {
  return arr;
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

Casos de teste fornecidos

largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]) deve retornar um array.

largestOfFour([[13, 27, 18, 26], [4, 5, 1, 3], [32, 35, 37, 39], [1000, 1001, 857, 1]]) deve retornar [27,5,39,1001].

largestOfFour([[4, 9, 1, 3], [13, 35, 18, 26], [32, 35, 97, 39], [1000000, 1001, 857, 1]]) deve retornar [9, 35, 97, 1000000].

Abordagem nº 1: Retornar os maiores números em um array com um laço for

Esta é a minha solução, com comentários incluídos para ajudar você a entendê-la:


function largestOfFour(arr) {
   // Passo 1. Crie um array que tenha o resultado de 4 subarrays
   var largestNumber = [0,0,0,0];
 
   // Passo 2. Crie o primeiro laço FOR, que percorrerá os arrays
   for(var arrayIndex = 0; arrayIndex < arr.length; arrayIndex++) {
   /* O ponto de partida, o índice 0, corresponde ao primeiro array */
 
    // Passo 3. Crie o segundo laço FOR, que percorrerá cada subarrays
    for(var subArrayIndex = 0; subArrayIndex < arr[arrayIndex].length; subArrayIndex++) {
    /* O ponto de partida, o índice 0, corresponde ao primeiro subarray */
       
       if(arr[arrayIndex][subArrayIndex] > largestNumber[arrayIndex]) {
          
          largestNumber[arrayIndex] = arr[arrayIndex][subArrayIndex];
          
       /* Ciclos dos laços FOR
          arrayIndex => i
          subArrayIndex => j
          
       Iteração no primeiro array
          Para cada iteração: arr[i][j]           largestNumber[i]          if arr[i][j] > largestNumber[i]?     then largestNumber[i] = arr[i][j]
          Primeira iteração:    arr[0][0] => 4      largestNumber[0] => 0     4 > 0? => TRUE                       then largestNumber[0] = 4
          Segunda iteração:   arr[0][1] => 5      largestNumber[0] => 4     5 > 4? => TRUE                       then largestNumber[0] = 5
          Terceira iteração:    arr[0][2] => 1      largestNumber[0] => 5     1 > 5? => FALSE                      then largestNumber[0] = 5
          Quarta iteração:   arr[0][3] => 3      largestNumber[0] => 5     3 > 5? => FALSE                      then largestNumber[0] = 5
          Quinta iteração:    arr[0][4] => FALSE  largestNumber[0] => 5                                          largestNumber = [5,0,0,0]
       Sair do primeiro array e continuar no segundo
       Iteração no segundo array
          Para cada iteração: arr[i][j]            largestNumber[i]           if arr[i][j] > largestNumber[i]?     then largestNumber[i] = arr[i][j]
          Primeira iteração:    arr[1][0] => 13      largestNumber[1] => 0      13 > 0? => TRUE                      then largestNumber[1] = 13
          Segunda iteração:   arr[1][1] => 27      largestNumber[1] => 13     27 > 13? => TRUE                     then largestNumber[1] = 27
          Terceira iteração:    arr[1][2] => 18      largestNumber[1] => 27     18 > 27? => FALSE                    then largestNumber[1] = 27
          Quarta iteração:   arr[1][3] => 26      largestNumber[1] => 27     26 > 27? => FALSE                    then largestNumber[1] = 27
          Quinta iteração:    arr[1][4] => FALSE   largestNumber[1] => 27                                          largestNumber = [5,27,0,0]
       Sair do primeiro array e continuar no terceiro
       Iteração no terceiro array
          Para cada iteração: arr[i][j]            largestNumber[i]           if arr[i][j] > largestNumber[i]?     then largestNumber[i] = arr[i][j]
          Primeira iteração:    arr[2][0] => 32      largestNumber[2] => 0      32 > 0? => TRUE                      then largestNumber[2] = 32
          Segunda iteração:   arr[2][1] => 35      largestNumber[2] => 32     35 > 32? => TRUE                     then largestNumber[2] = 35
          Terceira iteração:    arr[2][2] => 37      largestNumber[2] => 35     37 > 35? => TRUE                     then largestNumber[2] = 37
          Quarta iteração:   arr[2][3] => 39      largestNumber[2] => 37     39 > 37? => TRUE                     then largestNumber[2] = 39
          Quinta iteração:    arr[2][4] => FALSE   largestNumber[2] => 39                                          largestNumber = [5,27,39,0]
       Sair do primeiro array e continuar no quarto
       Iteração no quarto array
          Para cada iteração: arr[i][j]            largestNumber[i]           if arr[i][j] > largestNumber[i]?     then largestNumber[i] = arr[i][j]
          Primeira iteração:    arr[3][0] => 1000    largestNumber[3] => 0      1000 > 0? => TRUE                    then largestNumber[3] = 1000
          Segunda iteração:   arr[3][1] => 1001    largestNumber[3] => 1000   1001 > 1000? => TRUE                 then largestNumber[3] = 1001
          Terceira iteração:    arr[3][2] => 857     largestNumber[3] => 1001   857 > 1001? => FALSE                 then largestNumber[3] = 1001
          Quarta iteração:   arr[3][3] => 1       largestNumber[3] => 1001   1 > 1001? => FALSE                   then largestNumber[3] = 1001
          Quinta iteração:    arr[3][4] => FALSE   largestNumber[3] => 1001                                        largestNumber = [5,27,39,1001]
       Sair do laço FOR */
        }
    }
 }
 // Passo 4. Retornar os maiores números de cada um dos subarrays
 return largestNumber; // largestNumber = [5,27,39,1001];
}

largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

Aqui está ela, sem os meus comentários:


function largestOfFour(arr) {
   var largestNumber = [0,0,0,0];
   for(var arrayIndex = 0; arrayIndex < arr.length; arrayIndex++) {
    for(var subArrayIndex = 0; subArrayIndex < arr[arrayIndex].length; subArrayIndex++) {
       if(arr[arrayIndex][subArrayIndex] > largestNumber[arrayIndex]) {         
          largestNumber[arrayIndex] = arr[arrayIndex][subArrayIndex];
        }
    }
 }
 return largestNumber;
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

Abordagem nº 2: Retornar os maiores números em um array com funções integradascom map() e reduce()

Para esta solução, usarei dois métodos: o método Array.prototype.map() e o método Array.prototype.reduce().

  • O método map() cria um array com os resultados de chamar uma função dada em cada elemento desse array. Ao usar map, chamamos uma função de callback fornecida uma vez para cada elemento do array, em sequência, e criamos outro array a partir dos resultados.
  • O método reduce() aplica uma função a um acumulador e a cada valor do para reduzi-lo a um único valor.

O operador ternário é o único operador em JavaScript que recebe três operandos. Ele é usado como um atalho para a instrução if.

(currentLargestNumber > previousLargestNumber) ? currentLargestNumber : previousLargestNumber;

Podemos ler o mesmo da seguinte forma:

if (currentLargestNumber > previousLargestNumber == true) {
    return currentLargestNumber;
} else {
    return previousLargestNumber;
}

Aqui temos minha solução, com comentários incluídos:


function largestOfFour(mainArray) {
  // Passo 1. Usar Map nos arrays principais
  return mainArray.map(function (subArray){ // Passo 3. Retornar os maiores números de cada um dos subarrays => retorna [5,27,39,1001]

    // Passo 2. Pegar os maiores números de cada um dos subarrays com o método reduce()
    return subArray.reduce(function (previousLargestNumber, currentLargestNumber) {

      return (currentLargestNumber > previousLargestNumber) ? currentLargestNumber : previousLargestNumber;

      /* Ciclos de processamento dos métodos Map e Reduce
      currentLargestNumber => cLN
      previousLargestNumber => pLN
      Iteração no primeiro array
        Para cada iteração:     cLN         pLN       if (cLN > pLN) ?        then cLN        else pLN
          Primeira iteração:         4           0        4 > 0? => TRUE              4             /
          Segunda iteração:        5           4        5 > 4? => TRUE              5             /
          Terceira iteração:         1           5        1 > 5? => FALSE             /             5
          Quarta iteração:        3           5        3 > 5? => FALSE             /             5
          Quinta iteração:         /           5                                               returns 5
       Sair do primeiro array e continuar no segundo
      Iteração no segundo array
        Para cada iteração:     cLN         pLN       if (cLN > pLN) ?        then cLN        else pLN
        Primeira iteração:        13           0        13 > 0? => TRUE            13              /
        Segunda iteração:       27          13        27 > 13? => TRUE           27              /
        Terceira iteração:        18          27        18 > 27? => FALSE           /             27
        Quarta iteração:       26          27        26 > 27? => FALSE           /             27
        Quinta iteração:         /          27                                                returns 27
      Sair do primeiro array e continuar no terceiro
      Iteração no terceiro array
        Para cada iteração:     cLN         pLN       if (cLN > pLN) ?        then cLN        else pLN
        Primeira iteração:        32           0        32 > 0? => TRUE            32              /
        Segunda iteração:       35          32        35 > 32? => TRUE           35              /
        Terceira iteração:        37          35        37 > 35? => TRUE           37              /
        Quarta iteração:       39          37        39 > 37? => TRUE           39              /
        Quinta iteração:         /          39                                                returns 39
      Sair do primeiro array e continuar no quarto
      Iteração no quarto array
        Para cada iteração:     cLN         pLN       if (cLN > pLN) ?        then cLN        else pLN
        Primeira iteração:        1000         0        1000 > 0? => TRUE         1000             /
        Segunda iteração:       1001       1000       1001 > 1000? => TRUE      1001             /
        Terceira iteração:        857        1001       857 > 1001 => FALSE        /             1001
        Quarta iteração:        1         1001       1 > 1001? => FALSE         /             1001
        Quinta iteração:         /         1001                                              returns 1001
      Sair do primeiro array e continuar */
    }, 0); // 0 serve como contexto para o primeiro pLN em cada subarray
  });
}

largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

Aqui temos a versão sem comentários:


function largestOfFour(mainArray) {
  return mainArray.map(function (subArray){
    return subArray.reduce(function (previousLargestNumber, currentLargestNumber) {
      return (currentLargestNumber > previousLargestNumber) ? currentLargestNumber : previousLargestNumber;
    }, 0);
  });
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

Abordagem nº3: Retornar os maiores números em um array com funções integradascom map() e apply()

Para esta solução, você usará dois métodos: o método Array.prototype.map()  e o método Function.prototype.apply().

  • O método apply() chama uma função com um valor de this fornecido e os argumentos passados como um array (ou como um objeto semelhante a um array).

Você pode passar um array de argumentos para uma função usando o método apply() e a função executará os itens do array.

Essas funções são conhecidas como funções variádicas e podem aceitar vários argumentos em vez de um único argumento fixo.

A função Math.max() retorna o maior de zero ou mais números e podemos passar a ela quantos argumentos quisermos.

console.log(Math.max(4,5,1,3)); // registra 5

No entanto, não podemos passar um array de números ao método, desta forma:

var num = [4,5,1,3];
console.log(Math.max(num)); // registra NaN

É aqui que o método apply() passa a ser útil:

var num = [4,5,1,3];
console.log(Math.max.apply(null, num)); // registra 5

Observe que o primeiro argumento de apply() define o valor de 'this', não utilizado no método, o que faz com que passemos o valor null.

Agora que temos um método para retornar o maior número em um array, percorremos em laço cada subarray com o método map() e retornamos todos os maiores números.

Aqui temos minha solução, com comentários incluídos:


function largestOfFour(mainArray) {
  // Passo 1. Faz o mapping dos arrays principais
  return mainArray.map(function(subArray) { // Passo 3. Retorna o maior dos números de cada um dos subarrays => retorna [5,27,39,1001]
    
    // Passo 2. Retorna os maiores números para cada um dos subarrays com o método Math.max()
    return Math.max.apply(null, subArray);
  });
}

largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

E sem os comentários:


function largestOfFour(mainArray) {
  return mainArray.map(function(subArray) {
    return Math.max.apply(null, subArray);
  });
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

Espero que tenha achado este artigo útil. Ele é parte da minha série de artigos "Como resolver os algoritmos do FCC" sobre os desafios de algoritmos do freeCodeCamp, onde eu proponho várias soluções passo a passo mostrando o que acontece internamente em cada uma delas.

Três maneiras de repetir uma string em JavaScript
Neste artigo, eu explico como resolver o desafio "Repetir uma string Repetir uma string", do freeCodeCamp.
(texto em inglês)

Duas maneiras de confirmar o final de uma string em JavaScript
Neste artigo, eu explico como resolver o desafio "Confirmar o final", do freeCodeCamp.
(texto em inglês)

Três maneiras de inverter uma string em JavaScript
Este artigo tem por base o desafio de criação de scripts de algoritmos básicos "Inverter uma string", do freeCodeCamp.

Três maneiras de encontrar o fatorial de um número em JavaScript
Este artigo tem como base o desafio de criação de scripts de algoritmos básicos "Encontrar o fatorial de um número", do freeCodeCamp.

Duas maneiras de conferir palíndromos em JavaScript
Este artigo tem como base o desafio de criação de scripts de algoritmos básicos "Verificador de palíndromo", do freeCodeCamp.

Três maneiras de encontrar a maior palavra em uma string em JavaScript
Este artigo tem como base o desafio de criação de scripts de algoritmos básicos "Encontrar a palavra mais longa em uma string", do freeCodeCamp.
(texto em inglês)

Três maneiras de capitalizar a primeira letra de cada palavra de uma frase em JavaScript
Este artigo tem como base o desafio de criação de scripts de algoritmos básicos "Capitalizar a primeira letra de cada palavra de uma frase", do freeCodeCamp.
(texto em inglês)

Se tiver sua própria solução ou se tiver sugestões, compartilhe-as com a autora em algum dos links abaixo.

Você pode seguir a autora no Medium, no Twitter, no Github e no LinkedIn.

‪#‎StayCurious, ‪#‎KeepOnHacking‬ e ‪#‎MakeItHappen‬!

Recursos adicionais