Menu

Métodos de Array em JavaScript: map, filter, reduce e cia

Os métodos de array que substituem a maioria dos seus loops for — map, filter, reduce, find, some e every — e quais deles alteram o array original ou devolvem um novo.

Arrays vêm com uma caixa de ferramentas

Os arrays em JavaScript trazem um conjunto enorme de métodos prontos. Quase tudo que você faria com um for — transformar valores, escolher alguns, somar o total — tem um método que resolve em uma linha, lê melhor e ainda combina bem com os outros.

O kit inicial são três métodos: map, filter e reduce. Domine esses três, mais alguns primos próximos, e aquele seu código cheio de loops vira algo que dá pra entender de bate-pronto.

index.js
Output
Click Run to see the output here.

Cada método recebe um callback e devolve algum resultado. Repare que nenhum deles alterou nums — vale a pena gravar isso bem cedo.

map: transformando cada elemento do array

O array map em JavaScript recebe uma função e a executa em cada elemento, juntando os valores retornados num novo array do mesmo tamanho. Use quando você quer "uma saída para cada entrada".

index.js
Output
Click Run to see the output here.

O callback também recebe o índice como segundo argumento, caso você precise: arr.map((item, i) => ...). Quando não precisar, é só ignorar.

Um erro clássico: usar map quando você não precisa do array retornado. Se a ideia é só imprimir cada item ou salvar no banco, o certo é forEach ou um loop comum.

filter: mantendo só o que interessa

O filter executa um predicado — uma função que devolve true ou false — em cada elemento e mantém os que retornarem um valor "truthy". O array resultante tem o mesmo tamanho do original ou menos.

index.js
Output
Click Run to see the output here.

map e filter encaixam naturalmente em cadeia. Leia a sequência da esquerda para a direita como um pipeline:

index.js
Output
Click Run to see the output here.

Filtre primeiro e só depois faça o map — assim o map roda apenas sobre os que sobreviveram.

reduce: reduzindo um array a um único valor

O reduce é o mais versátil dos três. Você passa uma função redutora no formato (acumulador, item) => novoAcumulador e um valor inicial. Ele percorre o array, entrega cada item para o redutor junto com o acumulador atual e, no final, devolve o valor em que o acumulador terminou.

index.js
Output
Click Run to see the output here.

O resultado não precisa ser um número. Pode ser um objeto, outro array, uma string — qualquer coisa que você queira construir:

index.js
Output
Click Run to see the output here.

Sempre passe o valor inicial (o segundo argumento). Sem ele, o reduce usa o primeiro elemento como acumulador inicial, o que quebra em arrays vazios e, na maioria das vezes, nem é o comportamento que você queria.

O reduce é poderoso, mas fica difícil de ler quando a lógica começa a embolar. Se o seu reducer passa de umas poucas linhas, um for...of tradicional costuma ser bem mais claro.

forEach: efeitos colaterais, sem retorno

O forEach é tipo um map que não devolve array. Ele serve pra quando você quer fazer alguma coisa com cada item — dar um log, chamar uma API, atualizar o DOM — sem precisar gerar uma nova coleção.

index.js
Output
Click Run to see the output here.

Duas coisas importantes para saber:

  • forEach retorna undefined. Ou seja, não dá pra encadear um .map() depois.
  • Também não dá pra sair do forEach antes da hora com break. Se você precisar interromper no meio, use for...of ou some/every.

Se você se pegar escrevendo arr.forEach(x => results.push(transform(x))), isso é um map disfarçado.

find e findIndex: só um elemento, por favor

O find devolve o primeiro elemento que satisfaz a condição, ou undefined caso nenhum bata. Já o findIndex devolve o índice desse elemento (ou -1 se não achar nada).

index.js
Output
Click Run to see the output here.

find para no primeiro resultado que bate com a condição. Evite filter(...)[0] — isso varre o array inteiro só pra descartar o resto.

some e every: perguntas que retornam booleano

O some retorna true se pelo menos um elemento passar no teste. Já o every só retorna true quando todos passam.

index.js
Output
Click Run to see the output here.

Os dois fazem short-circuit — o some para na primeira ocorrência true, e o every para no primeiro false. São a ferramenta certa para responder perguntas do tipo "tem algum...?" / "todos são...?".

slice vs splice: copiar ou cortar

Os nomes são parecidos, mas o comportamento é bem diferente.

O slice(start, end) devolve uma cópia rasa de um trecho do array, sem mexer no original. O end é exclusivo; se você omitir, ele vai até o final.

index.js
Output
Click Run to see the output here.

splice(start, deleteCount, ...items) altera o array no lugar. Ele remove deleteCount elementos a partir da posição start, opcionalmente insere novos itens e retorna os elementos removidos.

index.js
Output
Click Run to see the output here.

Mnemônico: slice é seguro (copia), enquanto splice faz cirurgia direto no array original.

Métodos que mutam vs métodos que não mutam

Essa diferença faz toda a diferença no dia a dia. Código que altera sem querer um array compartilhado é um dos bugs mais chatos de rastrear.

Mutam (alteram o original e geralmente retornam outra coisa):

  • push, pop, shift, unshift
  • splice, sort, reverse
  • fill, copyWithin

Não mutam (retornam um novo array ou valor, sem mexer no original):

  • map, filter, slice, concat
  • flat, flatMap
  • find, findIndex, some, every, includes, indexOf
  • reduce, reduceRight

Os dois traiçoeiros são sort e reverse — parecem inofensivos e mutam o array sem avisar. Se você quer uma cópia ordenada, faça um slice antes:

index.js
Output
Click Run to see the output here.

O JavaScript moderno também traz as versões que não mutam o array: toSorted, toReversed, toSpliced e with. Elas devolvem um novo array e deixam o original intacto. Já funcionam em todos os runtimes atuais — então, sempre que puder, prefira essas.

index.js
Output
Click Run to see the output here.

flat e flatMap

O flat achata arrays aninhados em um nível (ou mais, se você passar a profundidade como argumento). Já o flatMap é um map seguido de um flat de um nível — bem útil quando cada item gera zero ou mais saídas.

index.js
Output
Click Run to see the output here.

flatMap é a forma elegante de "expandir" itens — uma entrada, várias saídas — sem precisar recorrer a um flat() depois.

Juntando tudo na prática

Um exemplo pequeno e realista. Dada uma lista de pedidos, calcule a receita total dos pedidos concluídos acima de R$ 50:

index.js
Output
Click Run to see the output here.

Três métodos, um pipeline, zero controle manual de loop. Cada etapa já diz o que faz. Dá pra fundir os dois filter em um só, mas separar fica legível — e às vezes ajuda bastante na hora de debugar.

A seguir: Map e Set

Arrays dão conta muito bem de sequências ordenadas, mas ficam desajeitados quando você precisa de busca rápida por chave ou de uma coleção de valores únicos. O JavaScript tem duas estruturas de dados nativas justamente pra esses casos — Map e Set — e é esse o tema da próxima página.

Perguntas frequentes

Qual a diferença entre map, filter e reduce em JavaScript?

map transforma cada elemento e devolve um novo array do mesmo tamanho. filter mantém só os elementos que passam no teste e devolve um novo array (geralmente menor). Já reduce percorre o array e reduz tudo a um único valor — pode ser uma soma, um objeto, outro array, o que você quiser construir.

Qual a diferença entre forEach e map?

forEach executa uma função para cada elemento e retorna undefined — é pensado para efeitos colaterais. Já map executa a função em cada elemento e devolve um novo array com os resultados. Se você quer um array transformado, use map. Se só precisa fazer algo por elemento e não liga pro resultado, use forEach (ou um for...of).

Quais métodos de array mutam o array original?

Os que mutam são push, pop, shift, unshift, splice, sort, reverse, fill e copyWithin. O resto — map, filter, slice, concat, flat, flatMap, find, some, every e reduce — não mexe no array original e devolve um valor novo.

Quando usar slice e quando usar splice?

slice(start, end) devolve uma cópia rasa de um trecho do array sem mexer no original. Já splice(start, deleteCount, ...items) muta o array — remove e/ou insere elementos no lugar e devolve os que foram removidos. Para lembrar: slice é seguro, splice faz cirurgia no array.

Aprenda a programar com o Coddy

COMEÇAR