Entendendo os métodos de array do Javascript - forEach, map, filter e reduce

Introdução

É muito comum trabalharmos com arrays seja qual for a linguagem de programação e no Javascript não é diferente.

Após o surgimento do Javascript ES6, novos métodos de array foram introduzidos. Muitos deles nos oferecem uma vantagem em comum, que é a redução de linhas de código.

Neste artigo, vamos destacar alguns deles. Mais precisamente: forEach, map, filter e reduce. Vamos falar sobre as funcionalidades de cada um, dar exemplos práticos de código e fazer algumas comparações com o for.

forEach

O forEach serve para percorrer os elementos de um determinado array e fazer alguma ação com esses elementos. Porém, essa ação não necessariamente precisa retornar algo, pois ele executa as funções no array original (tanto que forEach retorna undefined), ou seja, não retorna um novo array.

Um exemplo prático e simples de uso do forEach é quando temos um array de objetos e precisamos exibir os valores de cada item desse objeto.

Vamos criar um array de objetos pessoas contendo nome e idade.

const people = [
  {
    name: "Fulano",
    age: 18,
  },
  {
    name: "Beltrano",
    age: 20,
  },
];

Agora queremos exibir o nome e a idade de cada pessoa. Para isso, vamos iterar o array e imprimir os dados. Primeiro vamos fazer usando for:

for (const person of people) {
  console.log(`Nome: ${person.name} Idade: ${person.age}`);
}
// people[0]: Nome: Fulano Idade: 18
// people[1]: Nome: Beltrano Idade: 20

Agora vamos mostrar esse mesmo exemplo usando forEach, mas antes vamos explicar sobre seu argumento, uma callback que recebe dois argumentos, currentValue e index.

  • callback: Função executada a cada iteração (obrigatório). Pode ser usada a sintaxe arrow function;
    • currentValue: O valor atual do elemento do array (obrigatório);
    • index: O índice atual do elemento do array (opcional);

O exemplo acima com forEach ficaria da seguinte forma.

people.forEach((person) => {
  console.log(`Nome: ${person.name} Idade: ${person.age}`);
});
// people[0]: Nome: Fulano Idade: 18
// people[1]: Nome: Beltrano Idade: 20

Um outro exemplo de uso do forEach é quando precisamos exibir uma tabela de classificação.

const countries = [
  {
    name: "Holanda",
    points: 7,
  },
  {
    name: "Senegal",
    points: 6,
  },
  {
    name: "Equador",
    points: 4,
  },
  {
    name: "Catar",
    points: 0,
  },
];

Utilizando o parâmetro index conseguimos exibir a posição de cada time.

countries.forEach((country, index) => {
  console.log(`${index + 1}) ${country.name}: ${country.points}`);
});
// 1) Holanda: 7
// 2) Senegal: 6
// 3) Equador: 4
// 4) Catar: 0

map

O map é um método de iteração de array assim como o forEach, porém, ele nos retorna um array novo com a função de callback aplicada nele sem alterar o array original. Vejamos um exemplo prático:

A seguir, temos um array que representa os dados dos alunos, como o nome, sobrenome e nota.

const studentsData = [
  { firstName: "Fulano", lastName: "Tavares", points: 10 },
  { firstName: "Beltrano", lastName: "Real", points: 8 },
  { firstName: "Ciclano", lastName: "Almeida", points: 6 },
];

Vamos iterar sobre os dados e criar um novo array de objeto, passando o nome completo, o boletim escolar e utilizaremos o argumento index como forma de apresentar a classificação. Primeiro vamos fazer usando for:

const studentClassification = [];

for (const [index, student] of studentsData.entries()) {
  studentClassification.push({
    fullName: `${student.firstName} ${student.lastName}`,
    classification: index + 1,
    reportCard: student.points,
  });
}
console.log(studentClassification);

//[0] { fullName: 'Fulano Tavares', classification: 1, reportCard: 10 }
//[1] { fullName: 'Beltrano Real', classification: 2, reportCard: 8 }
//[2] { fullName: 'Ciclano Almeida', classification: 3, reportCard: 6 }

A seguir, faremos o mesmo exemplo com o map. Assim como o forEach, o map recebe uma callback onde podemos passar dois parâmetros. O exemplo acima, com o map, ficaria da seguinte forma:

const studentClassification = studentsData.map((student, index) => {
  return {
    fullName: `${student.firstName} ${student.lastName}`,
    classification: index + 1,
    reportCard: student.points,
  };
});

console.log(studentClassification);

//[0] { fullName: 'Fulano Tavares', classification: 1, reportCard: 10 }
//[1] { fullName: 'Beltrano Real', classification: 2, reportCard: 8 }
//[2] { fullName: 'Ciclano Almeida', classification: 3, reportCard: 6 }

filter

O método filter, como o próprio nome diz, serve para filtrar um array e é bem similar ao map, no sentido de que ele também devolve um novo array no final. A diferença fica no resultado do callback, que deve ser booleano.

Um bom exemplo de uso seria quando temos um array de objetos pessoas, onde queremos retornar um novo array apenas com as pessoas maiores de 18 anos.

const people = [
  {
    name: "Fulano",
    age: 18,
  },
  {
    name: "Beltrano",
    age: 20,
  },
  {
    name: "Ciclano",
    age: 16,
  },
];

Primeiro, vamos fazer um exemplo utilizando o for:

const olderAge = [];

for (const person of people) {
  if (person.age >= 18) {
    olderAge.push(person);
  }
}

console.log(olderAge);
//[0] {name: 'Fulano', age: 18}
//[1] {name: 'Beltrano', age: 20}
//length 2

Agora, faremos o mesmo exemplo utilizando o filter:

const olderAge = people.filter((person) => {
  return person.age >= 18;
});

console.log(olderAge);
//[0] {name: 'Fulano', age: 18}
//[1] {name: 'Beltrano', age: 20}
//length 2

Observe no código acima que foi retornado um novo array de length 2, que são justamente as duas pessoas maiores de idade.

Um outro exemplo bem simples de uso do filter é quando temos um array de números e queremos retornar um novo array apenas com os números pares.

const numbers = [1, 2, 3, 4, 5, 6];

const onlyEven = numbers.filter((number) => number % 2 === 0);
console.log(onlyEven); // [ 2, 4, 6 ]

Usando map e filter

Uma grande vantagem de retornar um novo array é combinar os métodos. Podemos usar o map e o filter em sequência, por exemplo.

Abaixo temos um array com dados de alguns jogadores, que atuam em diferentes clubes de futebol. Podemos usar o filter para iterar sobre os dados e nos retornar apenas os jogadores que atuam no Paris Saint-Germain. Assim como, em seguida, podemos utilizar o map para imprimir na tela uma apresentação desses jogadores.

const soccerPlayers = [
  { name: "Messi", soccerTeam: "Paris Saint-Germain" },
  { name: "Richarlison", soccerTeam: "Tottenham" },
  { name: "Neymar", soccerTeam: "Paris Saint-Germain" },
  { name: "De Bruyne", soccerTeam: "Manchester City" },
  { name: "Mbappé", soccerTeam: "Paris Saint-Germain" },
  { name: "Vini Junior", soccerTeam: "Real Madrid" },
];

const psgPlayers = soccerPlayers
  .filter((player) => {
    return player.soccerTeam === "Paris Saint-Germain";
  })
  .map((player) => {
    return `${player.name}, ${player.soccerTeam} player`;
  });
console.log(psgPlayers);
//[0] 'Messi, Paris Saint-Germain player'
//[1] 'Neymar, Paris Saint-Germain player'
//[2] 'Mbappé, Paris Saint-Germain player'

reduce

O método reduce, diferente do filter e do map que são métodos que nos retornam um novo array, pode também nos retornar qualquer outro tipo de dado, seja string, number, objeto, etc…

O reduce pode ter até dois parâmetros. O primeiro é o callback, e é obrigatório. Ele recebe como argumento o acumulador e o valor atual do índice. O segundo é o valor inicial, que é opcional. Ele é o valor a ser usado como primeiro argumento, da primeira chamada do callback.

Observação: Caso não seja passado nenhum valor inicial, o acumulador será igual ao primeiro índice no array, e valor atual será igual ao segundo índice.

Por exemplo, suponha que você tenha um array de uma lista de compras no mercado, onde você deseja calcular a soma do total gasto.

const marketList = [
  { description: "Brócolis", quantity: 1, price: 3 },
  { description: "Pasta de Amendoin", quantity: 2, price: 5 },
  { description: "Paçoca", quantity: 2, price: 6 },
];

Primeiro, vamos fazer um exemplo com o for:

let sum = 0;

for (const list of marketList) {
  sum += list.quantity * list.price;
}

console.log(sum);
// 25

Agora, faremos o mesmo exemplo utilizando o reduce:

const initialValue = 0;

const sumTotalListPrice = marketList.reduce(
  (sum, list) => sum + list.quantity * list.price,
  initialValue
);
console.log(sumTotalListPrice);
// 25

Conclusão

Neste artigo tentamos explicar alguns dos métodos de Array do JavaScript que são bem comuns no dia a dia dos desenvolvedores, ou seja, todos eles são bastante utilizados e com certeza você irá se deparar com eles.

Há diversos outros métodos de array conforme a documentação da MDN, mas optamos por destacar apenas alguns deles para o artigo focar no que mais usamos e não ficar muito extenso.

E você já utilizou esses métodos que destacamos acima? Tem alguma dúvida sobre eles? Compartilhe conosco nos comentários abaixo.

Referências