Funções em JavaScript: Array.filter()
Tags: javascript
Published: 2024-01-07 17:46:17

## Introdução

Listas são estruturas de dados que estão presentes no dia a dia de programadores. Cada linguagem de programação possui suas especificidades na implementação dessas estruturas, oferecendo diferentes métodos para se trabalhar com os dados nela armazenados.

O JavaScript oferece algumas funções especiais para manipular _listas/arrays_: as _HOF's (High Order Functions)_. Estas, basicamente, são funções que podem receber como parâmetro outras funções e também podem retornar uma função como resultado do seu processamento 🤯. Leia mais sobre [HOF's aqui](https://www.alura.com.br/artigos/high-order-functions).

Hoje vamos aprender sobre uma HOF que muito útil para quem precisa filtrar dados em uma lista: _filter()_.

## Problematização

Vamos considerar o seguinte cenário: nos foi dada uma lista de clientes cadastrados em um site. Esta lista, inclui clientes com cadastros ativos e inativos, e precisamos filtrar a partir dela somente os cliente com cadastro ativo.
Segue abaixo nossa lista:

```js
const clientes = [{
    'nome': 'Lucas',
    'ativo': true
  },
  {
    'nome': 'Maria',
    'ativo': false
  },
  {
    'nome': 'Mateus',
    'ativo': true
  },
  {
    'nome': 'Renan',
    'ativo': false
  },
  {
    'nome': 'Julya',
    'ativo': false
  },
  {
    'nome': 'Jéssica',
    'ativo': true
  }
]
```
Para filtrarmos esta lista, a solução mais intuitiva talvez seja estruturar um laço de repetição `for`:

```js
const clientesAtivos = []

for (let i = 0; i <= clientes.length - 1; i++) {
  if (clientes[i]['ativo']) {
    clientesAtivos.push(clientes[i])
  }
}

console.log(clientesAtivos)
/* Saída:
[
  { nome: 'Lucas', ativo: true },
  { nome: 'Mateus', ativo: true },
  { nome: 'Jéssica', ativo: true }
]
*/
```
Criamos uma laço de repetição `for` cuja variável de controle `i` começa em zero, porque vamos utilizá-la para acessar as posições do array, que como sabemos começa em 0. Essa variável será incrementada em +1 até que ela atinja a quantidade de elementos do array - 1, ou seja, a última posição do array, que é o seu número de elementos - 1.
Acessamos a chave `ativo` do objeto usando o ´[bracket notation`(notação de colchetes)](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Property_accessors). Como ela guarda um valor booleano, no bloco `if`, se for o valor for `true` o objeto será adiciona ao _array clientesAtivos_.
 
A solução acima funciona perfeitamente. Obteremos o resultado desejado. Porém, como programadores precisamos sempre pensar na melhor solução para um problema. Em muitos casos, haverão várias alternativas para solucionar o mesmo problema. E nestes casos, nosso trabalho é escolher a melhor alternativa para aquele problema, naquele contexto específico.

É possível resolver esse problema da filtragem da lista com código menor e maior legibilidade, diminuindo nossa chance erro e facilitando a vida de quem eventualmente venha a trabalhar no nosso código posteriormente.

## _filter()_

**[_filter()_](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)** é uma HOF do JavaScript, cujo objetivo é filtrar dados de um _array_ e armazenar o resultado em um novo _array_. Note que o _filter()_ não faz alterações no array em que ele é usado, ele cria um novo array e armazena nele os valores que atendem ao critério do filtro aplicado.

A sintaxe do filter é a seguinte:

```js
array.filter(function callback(valorAtual, indice, 
arrayOriginal) {});
```

- _callback_: função que é aplicada em todos os elementos do array;
- _valorAtual_: parâmetro obrigatório e é referente ao elemento que está sendo acessado no momento;
- _indice_: parâmetro opcional. Representa a posição do _valorAtual_ no _array_;
- _arrayOriginal_: parâmetro opcional. _Array_ original em que o _valorAtual_ está armazenado;

Podemos observar que o filter recebe obrigatoriamente uma função como parâmetro. Essa função é uma _callback_ ([aprenda sobre _callbacks_ aqui](https://www.freecodecamp.org/portuguese/news/funcoes-de-callback-em-javascript-o-que-sao-e-como-usa-las/)) que aplica um teste em cada elemento do array. Os valores que passam no teste são adicionados no novo _array_ que é retornado pelo _filter_.

Vamos aplicar o _filter_ para solucionar nosso problema de filtrar clientes ativos:

```js
const clientesAtivosFilter = clientes.filter(cliente => 
cliente['ativo']);

console.log(clientesAtivosFilter);

/**
Saída:
[
  { nome: 'Lucas', ativo: true },
  { nome: 'Mateus', ativo: true },
  { nome: 'Jéssica', ativo: true }
]
*/
```
Sim, resolvemos o mesmo problema com uma única linha de código. Esse é o poder do JavaScript!
Vamos entender como tudo isso está funcionando:

- chamamos o filter e passamos para ele uma _callback_ usando uma sintaxe mais curta, conhecida como [_arrow function_](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Functions/Arrow_functions);

- no parâmetro da _callback_, acessamos o elemento do _array_, que no caso é um objeto com as chaves `nome` e `ativo`;

- acessamos a chave `ativo`, e sendo ela `true` o objeto será adicionado ao _array_ criado e retornado pelo _filter_;

Vamos para um exemplo um pouco mais complexo. Considere a seguinte lista:

```js
const produtos = [
  {id: 1, descricao: "Smartphone", categoria: "Eletrônico", preco: 1000},
  {id: 2, descricao: "Notebook", categoria: "Eletrônico", preco: 3000},
  {id: 3, descricao: "Geladeira", categoria: "Eletrodoméstico", preco: 1800},
  {id: 4, descricao: "Liquidificador", categoria: "Eletrodoméstico", preco: 150},
  {id: 5, descricao: "Fogão", categoria: "Eletrodoméstico", preco: 500},
  {id: 6, descricao: "AirFryer", categoria: "Eletrodoméstico", preco: 600},
  {id: 7, descricao: "PS5", categoria: "Eletrônico", preco: 4500},
  {id: 8, descricao: "Smart TV 50 4k", categoria: "Eletrônico", preco: 3200},
  {id: 9, descricao: "Monitor Gamer", categoria: "Eletrônico", preco: 1800},
  {id: 10, descricao: "Máquina de Lavar", categoria: "Eletrodoméstico", preco: 1600}
];
```
O desafio agora é filtrar esses produtos pela categoria(Eletrônico) e preço(a partir de _2000R$_). A solução com filter ficaria assim:
 

```js
onst eletronicosCaros = produtos.filter(produto => produto.categoria === 'Eletrônico' && produto.preco >= 2000)

console.log(eletronicosCaros)

/**
Saída:
[
  {
    id: 2,
    descricao: 'Notebook',
    categoria: 'Eletrônico',
    preco: 3000
  },
  { id: 7, descricao: 'PS5', categoria: 'Eletrônico', preco: 4500 },
  {
    id: 8,
    descricao: 'Smart TV 50 4k',
    categoria: 'Eletrônico',
    preco: 3200
  }
]
*/
```
## Conclusão

_filter_ é um recurso poderoso que dispomos no JavaScript para trabalharmos com listas. Existem várias outras HOF's no JavaScript e você pode conferir algumas [aqui](https://medium.com/orangejuicefc/higher-order-functions-no-javascript-cce3b9aab426).

Disponibilizei esses códigos que usei como exemplo em um [repositório no meu GitHub](https://github.com/Lucas-GSS/dio/tree/main/artigos/javascript-filter). Fique a vontade para clonar, criar fork's e praticar.
Sugestões e feedbacks são sempre bem-vindos. Você pode me contactar no [LinkedIn](https://www.linkedin.com/in/lucas-gabriel7/)
Espero que este conteúdo tenha sido útil de alguma forma. Até mais!