Conhecendo map(), filter() e reduce() em JavaScript

27 de julho de 2022
Ronaldo B.

Manipular arrays é um dos trabalhos mais repetitivos que realizamos ao trabalhar com JavaScript. E há três métodos muito conhecidos que nos ajudam nessa manipulação: map(), filter() e reduce(). Eles são métodos conhecidos, mas nem sempre lembramos o objetivo de cada um deles.

Neste artigo iremos falar sobre as diferenças entre esses métodos e em quais situações eles podem nos ajudar.

Esses métodos possuem uma sintaxe mais sucinta e legível e nos permitem realizar em poucas linhas o que precisaríamos fazer com outros métodos para laço de repetição, como o método forEach() por exemplo. Vamos ver agora a definição desses métodos!

map() - Executa uma função em todos os itens de um array

O método map() tem o objetivo de executar uma função em cada item de um array. Essa afirmação talvez nos faça perguntar: “Mas não é isso o que o forEach() faz?” Realmente, o forEach() também manipula os dados de um array. Contudo, há uma diferença.

O método map() retorna um novo array após a manipulação, ou seja, não sobrescreve o array original. Na realidade, todos os métodos que iremos aprender neste artigo retornam um novo array como resposta.

Além disso, o método map() tem uma melhor performance do que o forEach(). Vamos ver um exemplo em que usar o map() nos permite realizar uma alteração nos dados de maneira bem simples.

Imagine que temos uma lista de produtos sendo exibidos em nossa página e desejamos adicionar um desconto de 10% no preço desses produtos. Como poderíamos fazer isso com o map()? Poderíamos ter um array de preços, como o abaixo:

const productsPrices = [100, 150, 300];

Daí, poderíamos chamar o método map() e armazenar seu retorno em uma nova variável, chamada de productsDiscount, desta forma:

const productsDiscount = productsPrices.map(price => {
  return price * 0.9;
});

Note que é necessário definir um return no método para que ele funcione. Sem o return o novo array teria todos os seus valores como undefined.

Como o nosso método apenas retornou o valor do preço, poderíamos simplificar ainda mais esse código, definindo-o em uma única linha:

const productsDiscount = productsPrices.map(price => price * 0.9);

Agora, se definirmos um console.log() na variável antiga e na nova, veremos o seguinte resultado:

Resultado de nosso código

Excelente! O array antigo continua inalterado, mas o novo está com os descontos definidos corretamente.

Neste exemplo nós usamos um array de preços, mas como poderíamos fazer isso com um objeto? Imagine que temos agora um array de objetos, que armazena as informações de nossos produtos:

const products = [{
  name: 'TV',
  price: 100
}, {
  name: 'Monitor',
  price: 150
}, {
  name: 'SSD',
  price: 300
}];

Como poderíamos aplicar os mesmos 10% de desconto neste caso? Uma solução é usar o método Object.keys() para encontrar os índices de nosso array de produtos, e executar o map() nestes índices. Assim, podemos alterar a chave do objeto de produtos em cada um de seus índices. Nosso código ficaria assim:

const productsDiscount = Object.keys(products).map(key => products[key]['price'] *= 0.9);

Dessa forma continuaria funcionando!

filter() - Filtra um array

O próximo método que iremos falar é o filter(). Como o próprio nome diz, ele tem o objetivo de filtrar as informações de um array. Sua funcionalidade consiste em informarmos para ele uma condição. Ele irá aplicar essa condição em todos os itens de nosso array e aqueles que se enquadrarem na condição serão retornados e adicionados ao novo array de saída. Dessa forma, diferente do que ocorre no map() e no reduce(), o filter() irá retornar sempre true ou false.

Talvez nos perguntemos: “Em que situações eu precisaria filtrar um array?”. É comum fazer isso quando estamos removendo um item de um array ou então filtrando os resultados de um array de dados.

Vamos criar um exemplo de remoção de um registro. Imagine que temos um array de usuários, com a seguinte estrutura:

const users = [1, 2, 3, 4];

Acabamos de excluir o usuário de id igual a 2 e desejamos removê-lo da página. Se estivéssemos usando algum framework JavaScript, como React, Angular ou Vue, poderíamos atualizar os dados da página sem precisar executar um refresh nela. Poderíamos usar este código:

const newUsers = users.filter(user => user !== 2);

O array newUsers irá conter todos os usuários que possuem id diferente de 2. Se executarmos um console.log() nas duas variáveis, veremos o seguinte resultado:

Resultado do filtro em nosso código

Note que o novo array não contém o usuário 2, exatamente o que desejávamos ?

reduce() - Reduz um array em um único resultado

O método reduce() é muito interessante e pode ser usado quando desejamos realizar alguma somatória ou então quando desejamos mesclar vários arrays em um único. Ele reduz todos os valores de um array em um único resultado, baseando-se na função que informamos para ele.

Os dois primeiros parâmetros desse método são muito importantes. O primeiro representa o resultado final da redução do array. Esse valor é incrementado ao longo do processo do reduce(), a cada volta desse laço de repetição. O segundo parâmetro envolve o valor de cada índice do array. Vamos ver um exemplo para ficar mais claro esse conceito para nós. ?

Imagine que possuímos uma variável que contém as informações do faturamento semestral de uma empresa. Esse array possui a seguinte estrutura:

const annualBilling = [1500, 1800, 700, 5000, 1600, 18000];

Agora imagine que desejamos saber qual foi o valor total do faturamento neste período. Precisaríamos realizar a soma de cada um dos valores deste array. O método reduce() poderia nos ajudar. Para isso bastaria somar o valor do total prévio em cada volta do laço de repetição com o valor corrente do faturamento em cada volta. Nosso código ficaria assim:

const totalBilling = annualBilling.reduce((total, currentValue) => {

  return total + currentValue;

}, 0);

Quando executarmos um console.log() na variável totalBilling, veremos o seguinte resultado:

Valor da soma dos valores do array

Muito bom! A soma foi realizada com sucesso. Note que o segundo parâmetro informado para o reduce() foi o número 0. Esse parâmetro representa a partir de qual número desejamos iniciar a nossa operação de soma. Por padrão esse valor é 0. Assim, não precisaríamos informá-lo neste caso, se não desejássemos.

Usando todos os métodos juntos

Esses três métodos são realmente incríveis. Mas, se eles já são incríveis sozinhos, imagine se pudéssemos usar os três juntos! Isso é completamente possível! Como cada um desses métodos retorna um novo array, podemos em seguida chamar outro método, realizando o que poderíamos chamar de um “encadeamento de métodos de array”.

Imagine que possuímos um array que armazena os funcionários de nossa empresa. Esse array possui a seguinte estrutura:

const employees = [{
  name: 'Luke',
  department: 'Financeiro',
  salary: 1500
}, {
  name: 'Han',
  department: 'Financeiro',
  salary: 1200
}, {
  name: 'Ben',
  department: 'Marketing',
  salary: 2000
}, {
  name: 'Leia',
  department: 'Marketing',
  salary: 1750
}, {
  name: 'Rey',
  department: 'Financeiro',
  salary: 1000
}]

Nós desejamos saber quanto que o Departamento Financeiro iria receber ao todo se déssemos 50% de aumento para eles. Para saber essa informação, nós precisaríamos: 1) filtrar do array quais são os funcionários do Departamento Financeiro, 2) adicionar 50% de aumento em seus salários e 3) fazer a somatória total desses salários. Poderíamos fazer isso usando os métodos que aprendemos neste artigo. Nosso código ficaria assim:

const totalSalary = employees.filter(employee => {

  return (employee.department === 'Financeiro');

}).map(item => {
  
  return item.salary *= 1.5;

}).reduce((total, currentValue) => {

  return total + currentValue;

});

Ao executar um console.log() na variável totalSalary, o seguinte resultado seria retornado:

Resultado de nosso código no console

Excelente! Descobrimos o valor total dessa operação.

Nós usamos acima a maneira “extensa”, definindo o return em cada um dos métodos. Contudo, como já vimos neste artigo, podemos simplificar esse código, deixando-o da seguinte maneira:

const totalSalary = employees
    .filter(employee => (employee.department === 'Financeiro'))
    .map(item => item.salary *= 1.5)
    .reduce((total, currentValue) => total + currentValue);

Agora sim, bem melhor!

Conclusão

Neste artigo vimos a diferença entre os métodos map(), filter() e reduce(). Aprendemos inclusive como usar esses três métodos em conjunto, para uma manipulação de arrays muito mais simples e prática.

Você pode aprender muito mais sobre arrays e outros conceitos fundamentais do JavaScript por meio de nosso Curso Completo de JavaScript, onde ensinamos os vários conceitos desta incrível linguagem através de projetos sensacionais.

Até o próximo artigo :)

Hcode: Utilizamos cookies para a personalização de anúncios e experiências de navegação dentro de nosso site. Ao continuar navegando, você concorda com as nossas Política de Privacidade.