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:
- com um laço FOR
- usando o método reduce()
- 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 arrayarr[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 integradas — com 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 integradas — com 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)
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!