
Map e Reduce no JavaScript – Guia rápido
Introdução
Nesse tutorial falaremos sobre os métodos de arrays do javascript Map e Reduce, veremos como eles funcionam e como utilizá-los na prática. Para acompanhar você só precisa ter o Node.js instalado na sua máquina ou então algum ambiente para executar código javascript, como o Codepen (https://codepen.io/pen/?editors=0010).
Map
- Crie um arquivo map.js e adicione inicialmente nele o array que usaremos no exemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const characters = [ { name: 'Frodo', race: 'Hobbit' }, { name: 'Sam', race: 'Hobbit' }, { name: 'Aragorn', race: 'Man' }, { name: 'Legolas', race: 'Elf' }, { name: 'Gimli', race: 'Dwarf' }, { name: 'Boromir', race: 'Man' }, { name: 'Merry', race: 'Hobbit' }, { name: 'Pippin', race: 'Hobbit' }, { name: 'Gandalf', race: 'Ainur' }, ] |
- Sem utilizar o map, poderíamos criar uma nova lista a partir dos dados dessa primeira utilizando o for da seguinte maneira:
1 2 3 4 5 6 7 8 |
// ... const list = [] for (let i = 0; i < characters.length; i++) { list.push(`${characters[i].name} is a ${characters[i].race}`) } |
- O método map existe para nos permitir transformar arrays, mais especificamente criar um novo array a partir de dados do anterior. Ele funciona recebendo uma função de callback que será executada uma vez para cada elemento do array e a cada execução ele obtém um elemento para incluir no novo array. Por isso, a função de callback recebe como parâmetro o elemento da iteração atual e deve retornar o valor que irá ser armazenado no novo array. No nosso exemplo poderíamos obter o mesmo resultado do for da seguinte maneira:
1 2 3 4 |
// ... const list = characters.map(character => `${character.name} is a ${character.race}`) |
- Poderíamos ainda separar a função de callback para organizar nosso código de uma forma diferente:
1 2 3 4 5 |
// ... const toString = character => `${character.name} is a ${character.race}` const list = characters.map(toString) |
Reduce
- Para entender o Reduce usaremos dois exemplos, um simples e outro um pouco mais elaborado. Para o nosso exemplo mais simples, crie um novo arquivo chamado reduce.js e dentro dele um array de números como mostrado a seguir:
1 2 |
const numbers = [3, 6, 4, 7, 3, 8, 10, 2] |
- Vamos somar todos os elementos desse array sem o Reduce usando um for:
1 2 3 4 5 6 7 8 |
// ... let sum = 0 for (let i = 0; i < numbers.length; i++) { sum += numbers[i] } |
- Agora veremos como funciona o Reduce. Assim como o Map, ele também serve para transformar arrays, porém a diferença é que ele transforma arrays em outros valores que não são necessariamente um array, como uma única string ou um único objeto.
- Como no Map, ele funciona iterando sobre o array e executando a cada elemento uma função de callback. Além disso, ele também acumula um valor entre cada iteração, e no fim esse é o valor único retornado pelo Reduce. Por isso, sua função de callback deve receber como parâmetros o valor acumulado vindo das iterações anteriores e o valor do elemento atual, e retornar o valor a ser passado para a iteração seguinte. Com isso é possível, por exemplo, somar todos os elementos de um array como fizemos com o for:
1 2 3 4 |
// ... const sum = numbers.reduce((accumulator, number) => accumulator + number, 0) |
- Para o nosso segundo exemplo, vamos reutilizar o array characters de antes:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const characters = [ { name: 'Frodo', race: 'Hobbit' }, { name: 'Sam', race: 'Hobbit' }, { name: 'Aragorn', race: 'Man' }, { name: 'Legolas', race: 'Elf' }, { name: 'Gimli', race: 'Dwarf' }, { name: 'Boromir', race: 'Man' }, { name: 'Merry', race: 'Hobbit' }, { name: 'Pippin', race: 'Hobbit' }, { name: 'Gandalf', race: 'Ainur' }, ] |
- Agora vamos criar um objeto a partir desse array contendo as quantidades de personagens de cada raça. Esse objeto terá como propriedades os nomes das raças e seus valores serão as respectivas quantidades:
1 2 3 4 5 6 7 |
// ... const races = characters.reduce((accumulator, character) => { accumulator[character.race] = accumulator[character.race] ? accumulator[character.race] + 1 : 1 return accumulator }, {}) |
- Também poderíamos utilizar a short-circuit evaluation do javascript para abreviar o operador ternário que verifica se o accumulator[character.race] está definido:
1 2 3 4 5 6 7 |
// ... const races = characters.reduce((accumulator, character) => { accumulator[character.race] = accumulator[character.race] + 1 || 1 return accumulator }, {}) |
- Caso queira entender por que e como funciona a short-circuit evaluation do javascript dê uma olhada na documentação em: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR#short-circuit_evaluation
E esses foram os métodos Map e Reduce. Caso queira conhecer mais sobre arrays do javascript e ainda aprender outros recursos avançados da linguagem dê uma olhada no nosso treinamento Programador Fullstack Javascript em https://programador.onebitcode.com.
Subscribe
0 Comentários