Métodos do Array: reduce - Javascript
front-end
tags:
- javascript
- ES6
- array
Postado em 12/10/2019
Olá! Neste post vou falar sobre o método reduce
para manipulação de arrays em Javascript. Esse método é bastante útil quando precisamos extrair um único valor baseado no valor de todos os itens do array.
Um contexto geral
O método reduce
(junto com o map e o filter) faz parte dos métodos de array que seguem os conceitos de programação funcional, sendo muito útil para extrair um resultado a partir de um conjunto de dados. Por isso o reduce
é muito útil e poderoso para, por exemplo, lidar com banco de dados NoSQL ou tratar um retorno de API.
Diferentemente do map
e do filter
que retornam um array com vários resultados, o reduce
retorna um único resultado.
Na tabela abaixo temos um resumo com a principal diferença do funcionamento de cada método:
método | descrição |
---|---|
map |
retorna um array do mesmo tamanho do original, com um valor processado pela função passada para cada item |
filter |
retorna um array apenas com os valores do array original que sejam selecionados pela função de filtro passada |
reduce |
retorna retorna apenas um único valor, combiando todos os itens do array original de acordo com a função passada |
Definição de reduce()
Antes de mostrar exemplos, vou deixar a deifinição da documentação da MDN. Recomendo que você visite essa documentação caso queira se aprofundar mais nos detalhes desse método.
O método
reduce()
executa uma função reducer (provida por você) para cada membro do array, resultando num único valor de retorno.
Sintaxe
O método reduce
recebe dois parâmetros, o primeiro é o callback e o segundo é o valor incial.
Callback
Callback é a função que vai ser aplicada para cada item do array, e seu retorno será passado para a próxima iteração. No final, valor retornado pelo reduce
será o valor retornado pelo callback na última iteração.
A função de callback recebe quatro argumentos: acumulador, valor atual, índice e array.
Acumulador:
Armazena o valor que será passado em cada iteração. Seu valor é o valor que foi retornado pela execução do callback da iteração anterior.
Na primeira iteração, o acumulador tem duas possibilidades de valor:
- se o valor inicial tiver sido passado para o
reduce
, esse será o valor do acumulador; - se o valor inicial não tiver sido passado, o valor do acumulador será o primeiro item do array.
Valor atual
É o valor do item do array que está sendo iterado.
Na primeira iteração, o valor atual tem duas possibilidades de valor:
- se o valor inicial tiver sido passado para o
reduce
, o valor atual será o primeiro item do array; - se o valor inicial não tiver sido passado, o valor atual será o segundo item do array.
Índice
É o índice do item do array na iteração atual. Por exemplo, 0
na primeira iteração, 1
na segunda e assim por diante.
Array
É o próprio array em que a função reduce
foi chamada.
Valor inicial
Este é o valor que será usado como acumulador
na primeira iteração. É importante lembrar que esse é um parâmetro opicional.
Retorno
O método reduce
irá retornar o valor que for retornado pela função de callback
na última iteração.
Exemplo
Exemplo 1: sem valor incial
Nesse primeiro exemplo, nosso objetivo é retornar a somatória de todos os itens de um array.
const numbersToSum = [0, 1, 2, 3, 4]
const callbackFunction = (acc, cur, idx, arr) => acc + cur
const sum = numbersToSum.reduce(callbackFunction) // sum = 10
A função callbackFunction
é chamada para cada item do array numbersToSum
e o retorno dela é passado para a próxima iteração.
Os parâmetros da callbackFunction
são:
acc
é o acumulador;cur
é o valor atual;idx
é o índice;arr
é o array, nesse caso onumbersToSum
;
No final, a constante sum
tem o valor de 10
, pois 0 + 1 + 2 + 3 + 4 = 10
.
A tabela abaixo mostra o processo a cada iteração:
iteração | acc | cur | idx | arr | retorno |
---|---|---|---|---|---|
1 | 0 | 1 | 1 | [0,1,2,3,4] |
1 |
2 | 1 | 2 | 2 | [0,1,2,3,4] |
3 |
3 | 3 | 3 | 3 | [0,1,2,3,4] |
6 |
4 | 6 | 4 | 4 | [0,1,2,3,4] |
10 |
Repare que o retorno
da última linha é o que é retornado pelo reduce
ao final do processo.
Exemplo 2: com valor incial
Nesse segundo exemplo, vamos ter o mesmo objetivo do exemplo anterior, mas dessa vez vamos passar um valor inicial para reduce
.
const numbersToSum = [0, 1, 2, 3, 4]
const callbackFunction = (acc, cur, idx, arr) => acc + cur
const initialValue = 5
const sum = numbersToSum.reduce(callbackFunction, initialValue) // sum = 15
A função callbackFunction
é chamada para cada item do array numbersToSum
e o retorno dela é passado para a próxima iteração, porém na primeira iteração, o parâmetro acc
tem o valor de initialValue
, que nesse caso é 5
.
Os parâmetros da callbackFunction
são:
acc
é o acumulador;cur
é o valor atual;idx
é o índice;arr
é o array, nesse caso onumbersToSum
;
O initialValue
representa o valor inicial que é passado para o reduce
.
No final, a constante sum
tem o valor de 15
, pois 5 + 0 + 1 + 2 + 3 + 4 = 15
.
A tabela abaixo mostra o processo a cada iteração:
iteração | acc | cur | idx | arr | retorno |
---|---|---|---|---|---|
1 | 5 | 0 | 0 | [0,1,2,3,4] |
5 |
2 | 5 | 1 | 1 | [0,1,2,3,4] |
6 |
3 | 6 | 2 | 2 | [0,1,2,3,4] |
8 |
4 | 8 | 3 | 3 | [0,1,2,3,4] |
11 |
5 | 11 | 4 | 4 | [0,1,2,3,4] |
15 |
Repare que o retorno
da última linha é o que é retornado pelo reduce
ao final do processo.
Conclusão
O método reduce
segue os seguintes passos:
- É feita uma iteração para cada elemento do array;
- Em cada iteração, uma função (o callback) é executado tendo quatro parâmetros: acumulador, valor atual, índice e array;
- O retorno dessa função de callback é passado para a próxima iteração através do acumulador;
- Ao final de todas as iterações, o valor do acumulador é retornado.
Lembrando que se for passado um valor inicial, na primeira iteração esse valor será usado no acumulador.
Em geral usamos o reduce
quando queremos processar ou combinar um conjunto de dados em um array e obter um resultado com um único valor no final.
Espero que esse post tenha te ajudado a entender um pouco melhor sobre o método reduce
.
Novamente, recomendo a leitura da documentação da MDN para se aprofundar no assunto.
Se tiver alguma dúvida ou sugestão de melhoria, é só deixar um comentário ou falar comigo nas redes sociais ;)