Você está na página 1de 13

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

JavaScript
Saiba mais sobre map(), filter() e reduce() e como usar estas importantes funções
de programação funcional em JavaScript.

25/07/2016

Tárcio Zemel

7min para ler

javascript básico da web

Buscar por...
Assine nossa newsletter e receba indicações
sensacionais 1 vez por mês!
Eu quero!

Já alguns anos, JavaScript chegou com métodos de manipulação de array mais


voltados à programação funcional. Neste artigo, conheça a utilidade das funções
map() , filter() e reduce() através de exemplos de códigos, parâmetros e casos
de uso.

Este artigo é baseado em JavaScript’s Map, Reduce, and Filter , do


SVBTLE de Dan Martensen .

Como programadores, construímos e manipulamos arrays de números, strings,


booleanos e objetos quase todos os dias. Nós os usamos para processar números,
coletar objetos, dar split em string, pesquisar, ordenar e muito mais. Mas qual é a
melhor maneira de trabalhar com arrays? Tradicionalmente, tem sido usar loops
para fazer a iteração nos elementos usando índice.

Em 2011, chegou em JavaScript map() , filter() e reduce() como alternativas


poderosas tanto para se trabalhar com valores cumulativos, quanto para criar
subconjuntos com base em condições. Estes métodos são úteis para reduzir a
complexidade, trabalhar sem “efeitos colaterais” e, muitas vezes, tornar o código
mais legível.

Desvantagens do loop
Buscar por...
Digamos que se está trabalhando em uma correção de bug e, vagueando por
1000 linhas de código JavaScript, eis que o seguinte loop se apresenta:

1 for ( var i = 0; i < array.length; i++ ) {


2     if ( array.indexOf( array[ i ] ) === i ) {
3         models.push(array[ i ] );
4     }
5 }

Foi possível ver que o loop serve para criar um novo array com elementos não
duplicados no original. Mas, para descobrir isso, foi necessária uma análise em 5
etapas:

Código:  var i = 0

Significado: Começa à esquerda do array

Código:  i < array.length

Significado: Termina à direita

Código:  i++

Significado: Incremento de 1 em 1

Código:  array.indexOf( array[ i ] ) === i

Significado: Se o valor é de primeira instância no array, vai coincidir com o índice (isso
significa que se está verificando uma duplicata)

Código:  models.push(...)

Significado:  models deve ser uma lista, mas quais dados ali constam? Quais são seus
tipos de dados? É preciso procurar um arquivo “models”. Enxaguar. Repetir.
Buscar por...
É necessário verificar 5 pedaços de informações para determinar o que está
acontecendo. E este é um único loop!

Uma abordagem funcional


Este mesmo objetivo poderia ser escrito usando o método filter() de JavaScript
da seguinte maneira:

1 var uniqueProducts = array.filter( function( elem, i, array ) {


2     return array.indexOf( elem ) === i;
3 } );

Simples e elegante.

Visto que filter() comunica comportamento de código, então é possível saber


exatamente o objetivo da função. Em comparação com a abordagem de looping
acima:

Checar #1, #2 e #3 é desnecessário, já que filter() faz isso


automaticamente.
#4 é o mesmo, mas sem o adicional de checagem do bloco if .
Um grande obstáculo foi #5 — lembra-se do número de questões que ele
suscitava? map() , filter() e reduce() resolvem esse tipo de problema ao não
dependerem de código fora dos callbacks.

No final das contas, map() , filter() e reduce() fazem do código menos


complexo, sem efeitos colaterais e, freqüentemente, mais legível.

Buscar por...
map()

Funções de Array JavaScript - Aula 1 - map()

Use map() quando: é preciso traduzir/mapear todos os elementos em um array


para outro conjunto de valores.

Exemplo: converter temperatura de Fahrenheit para Celsius.

1 var fahrenheit = [ 0, 32, 45, 50, 75, 80, 99, 120 ];


2  
3 var celcius = fahrenheit.map( function( elem ) {
4     return Math.round( ( elem - 32 ) * 5 / 9 );
5 } );
6  
7 // ES6
8 // fahrenheit.map( elem => Math.round( ( elem - 32 ) * 5 / 9 ) );
9  
Buscar por...
10 celcius //  [ -18, 0, 7, 10, 24, 27, 37, 49 ]
O que map() faz: percorre o array da esquerda para a direita invocando uma
função de retorno em cada elemento com parâmetros. Para cada chamada de
retorno, o valor devolvido se torna o elemento do novo array. Depois que todos os
elementos foram percorridos, map() retorna o novo array com todos os elementos
“traduzidos”.

Parâmetros:

1 array.map( function( elem, index, array ) {


2     ...
3 }, thisArg );

Parâmetro:  elem

Significado: Valor do elemento

Parâmetro:  index

Significado: Índice em cada iteração, da esquerda para a direita

Parâmetro:  array

Significado: Array original invocando o método

Parâmetro:  thisArg

Significado: (opcional) Objeto que será referenciado como this no callback

filter()
Buscar por...
Use filter() quando: é preciso remover elementos indesejados com base em
alguma(s) condição(ões).

Exemplo: remover elementos duplicados de um array.

1 var uniqueArray = array.filter( function( elem, index, array ) {


2     return array.indexOf( elem ) === index;
3 } );
4  
5 // ES6
6 // array.filter( ( elem, index, arr ) => arr.indexOf( elem ) === index );

O que filter() faz: como map() , filter() percorre o array da esquerda para a
direita invocando uma função de retorno em cada elemento. O valor retornado
deve ser um booleano que indica se o elemento será mantido ou descartado.
Depois de todos os elementos terem sido analisados, filter() retorna um novo
array com todos os elementos que retornaram como verdadeiro.

Buscar por...
Parâmetros (os mesmo que map() ):

1 array.filter( function( elem, index, array ) {


2     ...
3 }, thisArg );

Parâmetro:  elem

Significado: Valor do elemento

Parâmetro:  index

Significado: Índice em cada iteração, da esquerda para a direita

Parâmetro:  array

Significado: Array original invocando o método

Parâmetro:  thisArg

Significado: (opcional) Objeto que será referenciado como this no callback

reduce()

Buscar por...
Use reduce() quando: é preciso encontrar um valor cumulativo ou concatenado
com base em elementos de todo o array.

Exemplo: soma de lançamentos de foguetes orbitais no período de 1 ano.

1 var rockets = [
2     { country:'Russia', launches:32 },
3     { country:'US', launches:23 },
4     { country:'China', launches:16 },
5     { country:'Europe(ESA)', launches:7 },
6     { country:'India', launches:4 },
7     { country:'Japan', launches:3 }
8 ];
9  
10 var sum = rockets.reduce( function( prevVal, elem ) {
11     return prevVal + elem.launches;
12 }, 0 );
13  
14 // ES6
15 // rockets.reduce( ( prevVal, elem ) => prevVal + elem.launches, 0 );
16  
17 sum // 85

Se ficou com dúvidas na notação de rockets , leia o artigo sobre


JSON .
Buscar por...
O que reduce() faz: como map() , reduce() percorre o array da esquerda para a
direita invocando uma função de retorno em cada elemento. O valor retornado é o
valor acumulado passado de callback para callback. Depois de todos os
elementos terem sido avaliados, reduce() retorna o valor
acumulado/concatenado.

Parâmetros:

1 array.reduce( function( prevVal, elem, index, array ) {


2     ...
3 }, initialValue );

Parâmetro:  prevVal

Significado: Valor cumulado retornado em cada iteração

Parâmetro:  elem

Significado: Valor do elemento

Parâmetro:  index

Significado: Índice em cada iteração, da esquerda para a direita

Parâmetro:  array

Significado: Array original invocando o método

Parâmetro:  initialValue

Significado: (opcional) Objeto usado como primeiro argumento na primeira iteração

Buscar por...
(mais à esquerda)
Conclusão sobre map() , filter() e
reduce() em JavaScript
Como informações extras sobre map() , filter() e reduce() , dá-se que:

Cada um deles é um método no objeto de protótipo (prototype) Array


Alterar um elemento no parâmetro array em qualquer callback persistirá
através de todos os callbacks restantes, mas não apresentará quaisquer
efeitos no array retornado
Funções de callback são invocadas nos índices com qualquer valor, até
undefined , mas não valores excluídos ou que nunca tiveram um valor
atribuído

Caso tenha dúvidas sobre a sintaxe de ECMAScript 6, conheça o


repo es6features , com resumo das principais funcionalidades de
ES6 com exemplos de códigos.

Importante ressaltar, também, que map() , filter() e reduce() não vieram para
substituir loops que, definitivamente, ainda têm seu lugar em diversas situações
— como, por exemplo, ao se trabalhar com grandes arrays (mais de 1k elementos)
ou quando é preciso parar a iteração se determinada(s) condição(ões) for(em)
atendida(s) ( break ).

Para continuar a conhecer as principais funções de array JavaScript, leia também


nosso artigo every(), some(), find() e includes() em JavaScript .
Buscar por...
CSS acessível Entenda CORS de uma vez
por todas!

7 alternativas à <div> para every(), some(), find() e


uma Web mais semântica includes() em JavaScript

Conheça os tópicos do desenvolvimento para web

CSS • Design • HTML • Indicações • JavaScript • Miscelânea • PHP • SEO • UX


• WordPress • Acessibilidade • Análise • Animação CSS • API
• Arquitetura da Informação • Básico da Web • Boas Práticas • Carreira
• Clientes • CSS Grid • dpw expo • Entrevista • Estratégia de Conteúdo
• Ferramentas • Flexbox • Gamificação • Interface • jQuery • Layout • Motion UI
• Performance • Planejamento • Portfolio • React • Resenha • Sass • Segurança
• Séries • Svelte • Tipografia • Usabilidade • Web Design
• Web Design Responsivo

Buscar por...
Facebook do dpw
Instagram do dpw
YouTube do dpw

Twitter do dpw
desenvolvimento para web é mantido pela
webfatorial e usa a licença
WTFPL.

Você também pode gostar