Higher Order Functions no JavaScript

Aprenda a manipular Arrays com a mágica das HOF

Bruno Brolesi
orangejuicetech
6 min readJul 22, 2021

--

Grande parte das pessoas que começam na programação sentem dificuldades em manipular estruturas como os Arrays. Começamos utilizando aqueles maravilhosos for, while e do while, mas no final o código fica parecendo a pia de casa depois de um jantar em família, e nem te conto quem vai ter que lavar tudo depois 😢.

Por esse motivo, hoje vim aqui te apresentar as queridinhas dos desenvolvedores JavaScript, as Higher Order Functions. As HOF são definidas como funções que aceitam funções como parâmetro e/ou retorna a função como saída.

🤔 Ficou meio confuso? 🤔 Vou te mostrar alguns exemplos e te garanto que vai ficar mais nítido.

As HOF que iremos ver nesse artigo são:

  • Array.prototype.find
  • Array.prototype.filter
  • Array.prototype.forEach
  • Array.prototype.map
  • Array.prototype.reduce

1- Array.prototype.find

Digamos que nós temos um array com os valores: 10, 15, 20, 25 e 30, e queremos selecionar o primeiro número maior que vinte. Uma maneira de fazermos isso é com o seguinte código:

Entretanto o método find simplifica nossa vida, ele retorna o valor do primeiro elemento do array que atender a função de teste fornecida como argumento, e caso não encontre nenhum resultado, o valor retornado é undefined. Bora para um exemplo:

No exemplo exemplo acima, é criado um array contendo os números: 10, 15, 20, 25, 30. Logo em seguida, nossa intenção é capturar o primeiro elemento maior que 20, então utilizamos o método find.

A linha 3 pode ser lida da seguinte forma, percorra cada elemento do array, e retorne o primeiro elemento maior que vinte.

A arrow funtion passada como argumento para o método find vai ser executada para cada elemento do array, verificando se ele atende a expressão de teste elemento > 20, se o resultado for verdadeiro, o elemento é retornado.

Na linha 5, ao imprimirmos a variável maiorQueVinte obteremos o valor 25.

Não é necessário passar arrow funcitons como argumentos dos métodos mostrados aqui, podemos utilizar uma função normal, como no exemplo a seguir:

Podemos perceber que ao invés de escrevermos uma arrow function como argumento, declaramos uma função chamada callback que recebe um elemento, e essa função é passado como argumento no find. Por preferência, todos os demais exemplos serão mostrados utilizando arrow functions.

2- Array.prototype.filter

Alterando um pouco o exemplo anterior, agora temos um array com os mesmo valores e queremos selecionar todos os números maiores que vinte. Uma maneira de fazermos isso é com o seguinte código:

Entretanto, o método filter simplifica muito a escrita desta operação, ele retorna um novo array com todos os elementos que satisfaçam a expressão de teste fornecida como argumento, e caso não encontre nenhum resultado, o valor retornado é undefined. Bora para um exemplo:

Agora utilizando o método filter para obtermos todos os elementos maiores que 20.

A linha 3 pode ser lida como, percorra cada elemento do array e nos retorne todos os elementos maiores que vinte.

A arrow funtion passada como argumento para o método filter vai ser executada para cada elemento do array, verificando se o elemento atende a expressão de teste elemento > 20, se o resultado for verdadeiro o elemento fará parte do array retornado.

Na linha 5, ao imprimirmos a variável maioresQueVinte obteremos o array contendo 25 e 30.

Dica: Outra ótima aplicação do método filter é para remover elementos indesejados de um array, por exemplo:

Agora queremos todos os elementos do array inicial exceto o 20.

Utilizando o filter e fornecendo a arrow function com a expressão de teste elemento !== 20, a função irá nos retornar um array com todos os elementos iniciais e irá excluir o 20 do resultado. Lembrando que o filter não altera o array original, ele gera um novo array como resultado.

3- Array.prototype.forEach

Agora queremos imprimir uma mensagem personalizada para cada elemento do nosso array no padrão array[ index ] = elemento. Uma maneira de fazermos isso é com o seguinte código:

Outro ponto que iremos abordar aqui, e que não é exclusivo do forEach, são os parâmetros opcionais fornecido para a callback . Nos exemplos anteriores, a callback recebia apenas o elemento atual do array, entretanto existem os parâmetros opcionais index e array:

  • elemento: O valor atual do elemento sendo processado no array.
  • index (opcional): O índice do elemento atual sendo processado no array.
  • array (opcional): O array em que o forEach está sendo aplicado.

Tendo isso em mente, o método forEach executa uma dada função em cada elemento de um array e diferente das funções anteriores, o forEach não possui um retorno. Preste muita atenção nessa parte do retorno, se tentarmos armazenar o resultado do forEach em uma variável, receberemos somente o valor undefined. Bora para um exemplo:

Agora utilizando o método forEach para imprimirmos nossas mensagens personalizadas.

A linha 3 pode ser lida como, percorra cada elemento do array e imprima a mensagem no padrão array[ index ] = elemento.

A arrow funtion passada como argumento para o método forEach, além de receber elemento também recebe o index e vai ser executada para cada elemento do array imprimindo a mensagem que informamos.

Ao executarmos a Linha 3, o resultado obtido é o código comentado.

4- Array.prototype.map

Continuando nosso exemplo das mensagens personalizadas, mas ao invés de imprimirmos cada mensagem, agora queremos salvar todas elas em um array. Uma maneira de fazermos isso é com o seguinte código:

Outra maneira de realizar esse tipo de operação é utilizando o método map, ele executa a função callback passada por argumento para cada elemento do array e devolve um novo array como resultado. Bora pro exemplo:

Agora utilizando o método map para criarmos nossos array de mensagens personalizadas.

A linha 3 pode ser lida como, percorra cada elemento do array e armazene o retorno da arrow function no array resultante, no caso o retorno é a mensagem no padrão array[ index ] = elemento.

E ao executarmos a Linha 5, o resultado obtido é o código comentado, um array com todas as mensagens.

5- Array.prototype.reduce

E para fecharmos com chave de ouro, agora teremos um array com os valores: 1, 2 e 3, e queremos obter a soma de todos os elementos desse array. Uma maneira de fazermos isso é com o seguinte código:

Uma forma mais simples de realizar essa mesma operação é com o reduce, ele executa uma função reducer (fornecida por você) para cada elemento do array, resultando em um único valor de retorno.

O reduce possui uma pequena diferença em relação ao métodos que vimos anteriormente, a callback que ele recebe possui como primeiro argumento um acumulador.

O acumulador irá acumular o retorno de cada iteração sobre o array. Execute o código abaixo e tudo ficará mais nítido.

O acumulador começa com o valor 1 e o elementoAtual começa com o valor 2, pois eles são o primeiro e segundo elemento do array respectivamente.

Na segunda interação o acumulador passa a valer 3, pois é a soma de 1 + 2. Já o elementoAtual também vale 3, pois é o valor do terceiro elemento do array.

Ao imprimirmos a soma total na linha 10, obtemos o valor 6, pois foi a ultima operação realizada no reduce, somando 3 + 3.

Um último ponto, e se quisermos que o acumulador não comece com o valor do elemento inicial do array? Podemos fazer isso adicionando um argumento com o valor inicial do acumulador após a callback, veja o exemplo:

No código acima, acumulador começa com o valor 3 e o elementoAtual começa com o valor 1, pois ele possuirá o valor do primeiro elemento do array e o acumulador será iniciado com o valor que informamos, no caso 3.

Na segunda interação o acumulador passa a valer 4, pois é a soma de 3 + 1. Já o elementoAtual vale 2, pois é o valor do segundo elemento do array.

Na terceira interação o acumulador passa a valer 6, pois é a soma de 4 + 2. Já o elementoAtual vale 3, pois é o valor do terceiro elemento do array.

Ao imprimirmos a soma total na linha 8, obtemos o valor 9, pois foi a ultima operação realizada no reduce, somando 6+ 3.

Conclusão

Foi bastante coisa né pessoal? Peguem todos esses códigos que foram passados aqui e executem nas suas máquinas, modifiquem, busquem exercícios e aprendam. Uma dica de ouro, dominem as Higher Order Functions, pois elas vão facilitar muito a sua vida e tornar seu código muito mais limpo.

Referências

--

--