Manipulação de arrays é uma tarefa do cotidiano de todo programador. Quem é que nunca precisou pegar uma listagem de items e extrair só os ids, ou precisou filtrar somente os itens que respeitassem determinado parâmetro ou então precisou somar o valor total de todos os items?

Para quem vem de outras linguagens, é comum utilizar estruturas como while , for e for each para tais manipulações. No Javascript, também é possível manipular arrays dessa forma, porém, há outras maneiras que na minha opinião, tornam o código mais simples e agradável. Nesse artigo veremos três funções do Array.prototype que podem nos ajudar a explorar essas outras maneiras: map, filter e reduce.

Map

O método Array.map permite que você aplique uma transformação para cada elemento do seu array, gerando um novo array como resultado. Imagine que você possui um array com números:

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

O seu objetivo, é pegar cada número desse array e multiplicá-lo por 2. O código ficaria da seguinte maneira:

os códigos abaixo podem ser copiados e colados na aba console , no inspector do seu navegador

const numeros = [ 1 , 2 , 3 , 4 , 5 , 6 ] ; const duplicar = x => x * 2 ; const duplicados = numeros . map ( duplicar ) ; console . log ( duplicados )

No código acima, nós:

definimos uma função duplicar que aceita um número x e retorna o valor dele multiplicado por 2.

que aceita um número e retorna o valor dele multiplicado por 2. Passamos essa função duplicar para o .map e atribuímos o resultado map a const duplicados.

O map por sua vez, vai percorrer o array de números e para cada item ele vai executar a função duplicar , passando o item como argumento, e irá utilizar os resultados para construir um novo array

Não existe a necessidade de definir a função primeiro, você pode definir ela inline:

const numeros = [ 1 , 2 , 3 , 4 , 5 , 6 ] ; const duplicados = numeros . map ( x => x * 2 ) ; console . log ( duplicados )

Você deve estar pensando: “Ok, mas quando é que eu vou precisar duplicar números na vida real?”

Realmente, mas a ideia do exemplo era ser o mais simples possível, só para você pegar a ideia. Mas agora imagine a situação onde você tem uma lista de produtos e precisa extrair id de cada um?

const produtos = [ { id : 1 , categoria : 'limpeza' , name : 'Amaciante' } , { id : 2 , categoria : 'limpeza' , name : 'Detergente' } , { id : 3 , categoria : 'alimento' , name : 'ovo' } , { id : 4 , categoria : 'alimento' , name : 'alface' } , ] const ids = produtos . map ( p => p . id ) ; console . log ( ids ) ;

Outro exemplo bem comum, é a criação de listas no React:

const produtos = [ { id : 1 , categoria : 'limpeza' , name : 'Amaciante' } , { id : 2 , categoria : 'limpeza' , name : 'Detergente' } , { id : 3 , categoria : 'alimento' , name : 'ovo' } , { id : 4 , categoria : 'alimento' , name : 'alface' } , ] ; function List ( ) { return ( < ul > { produtos . map ( p => ( < li key = { p . id } > { p . name } </ li > ) ) } </ ul > ) ; }

Acima, o map executa a função passando cada produto e obtem um elemento React em troca.

Filter

O Array.filter, como o próprio nome já sugere, serve para filtrar itens de um array. Digamos que você tenha a mesmo array de produtos, mas dessa vez, você só quer que fique no array, os produtos com a categoria “alimento”:

const produtos = [ { id : 1 , categoria : 'limpeza' , name : 'Amaciante' } , { id : 2 , categoria : 'limpeza' , name : 'Detergente' } , { id : 3 , categoria : 'alimento' , name : 'ovo' } , { id : 4 , categoria : 'alimento' , name : 'alface' } , ] ; const isAlimento = produto => produto . categoria === 'alimento' ; const alimentos = produtos . filter ( isAlimento ) ; console . log ( alimentos ) ;

O Array.filter executa a função isAlimento para cada item do array. Se a função retornar um valor truthy, o item permanece na lista, caso retorne falsy, o item é removido da lista.

É importante ressaltar que tanto o map quanto o filter e o reduce criam novas instancias do array. Os arrays originais continuam inalterados.

Agora imagina combinar o map e o filter juntos?

Imagine que você quer os ids dos produtos, mas somente dos alimentos:

const produtos = [ { id : 1 , categoria : 'limpeza' , name : 'Amaciante' } , { id : 2 , categoria : 'limpeza' , name : 'Detergente' } , { id : 3 , categoria : 'alimento' , name : 'ovo' } , { id : 4 , categoria : 'alimento' , name : 'alface' } , ] ; const idsAlimentos = produtos . filter ( p => p . categoria === 'alimento' ) . map ( p => p . id ) ; console . log ( idsAlimentos ) ;

Bem simples não?

Reduce

Entre os três, o reduce pode parecer o mais complexo. Mas conforme os exemplos, você verá que ele é simples de ser utilizado.

A ideia do reduce, é produzir um único valor a partir de um array. Imagine que você tem uma lista de números e que você quer saber a soma total de todos eles.

const numeros = [ 1 , 2 , 3 , 4 ] ; const somar = ( acumulado , x ) => acumulado + x ; const total = numeros . reduce ( somar ) ; console . log ( total ) ;

O reduce executa a função de somar passando o valor acumulado e o próximo item do array.

Vamos ver passo a passo, olhando dentro da função callback (somar):

const numeros = [ 1 , 2 , 3 , 4 ] ; const total = numeros . reduce ( ( acumulado , x ) => { console . log ( ` ${ acumulado } + ${ x } = ${ acumulado + x } ` ) ; return acumulado + x ; } ) ;

Como é a primeira iteração, o reduce chamará a função callback, passando o primeiro e o segundo elemento do array. A função callback retornará 3 e esse se tornará o resultado acumulado.

Na segunda interação, o reduce chama a função callback passando o valor acumulado e o terceiro item do array. Somar retorna 6, que por sua vez, se torna o valor acumulado.

Na terceira iteração, será executada a função callback com o valor acumulado e o quarto item. A função somar retorna 10. Como não há mais itens no array, esse se torna o resultado final, que é atribuído a const total;

Trazendo o uso dele para o mundo real, imagine que gostariamos de somar os valores de todos os produtos de uma lista:

const produtos = [ { valor : 6.50 , id : 1 , categoria : 'limpeza' , name : 'Amaciante' } , { valor : 1.20 , id : 2 , categoria : 'limpeza' , name : 'Detergente' } , { valor : 6.90 , id : 3 , categoria : 'alimento' , name : 'ovo' } , { valor : 2.00 , id : 4 , categoria : 'alimento' , name : 'alface' } , ] ; const total = produtos . reduce ( ( acumulado , produto ) => { if ( acumulado . valor ) { return acumulado . valor + produto . valor ; } return acumulado + produto . valor ; } ; console . log ( total ) ;

Observe que tivemos que colocar uma condicional, identificando se acumulado tinha ou não a propriedade valor . Isso porque na primeira iteração, são passados o primeiro e o segundo elemento do array, os dois sendo objetos. Já na segunda iteração, acumulado é um número e não mais um objeto. Há uma maneira de deixar isso mais simples. O Array.reduce aceita além da função callback, um segundo parâmetro, para se tornar o valor inicial de acumulado , que no nosso caso, será 0 :

const produtos = [ { valor : 6.50 , id : 1 , categoria : 'limpeza' , name : 'Amaciante' } , { valor : 1.20 , id : 2 , categoria : 'limpeza' , name : 'Detergente' } , { valor : 6.90 , id : 3 , categoria : 'alimento' , name : 'ovo' } , { valor : 2.00 , id : 4 , categoria : 'alimento' , name : 'alface' } , ] ; const total = produtos . reduce ( ( acumulado , produto ) => acumulado + produto . valor , 0 ) ; console . log ( total ) ;

Quando passamos um valor inicial, a sequencia das iterações sofre uma pequena mudança, ao invés de ser passado o primeiro e o segundo item do array, é passado o valor inicial e o primeiro item. E depois o fluxo segue, passando o valor acumulado e o próximo item do array.

Para conseguir fixar bem a ideia, eu criei um sandbox com esse código, já com alguns console.log dentro do reduce: sandbox Abra o console, edite o código e veja os resultados. A melhor maneira de aprender, é colocando a mão na massa.

Gostou do post e das dicas? Ajude-nos a divulgar compartilhando nas redes sociais para que mais pessoas tenham acesso! ❤️️

Não esqueça de se inscrever na nossa newsletter