8 truques simples para filtrar arrays de forma eficiente e eficaz

Javascript

Neste post vou falar sobre alguns truques do JavaScript filter() que você precisa saber. Esses truques vão te ajudar a usar o método filter() de forma mais eficiente e eficaz.

O método filter() é uma ferramenta fácil de entender, mas pode ser um pouco complicado de usar, especialmente quando você quer fazer coisas mais avançadas. Essas dicas que vou compartilhar vão te ajudar a evitar alguns dos problemas mais comuns.

Introdução

Quer limpar, remover ou simplesmente selecionar alguns elementos específicos? O filter() é a sua ferramenta principal.

Já precisou tratar um conjunto de dados gigante usando JavaScript? A propósito, existem maneiras de evitar isso, como paginação, mas não vou entrar nesse mérito aqui mas vamos imaginar que você já recebeu no front-end ou em algum aplicativo Node.js, uma lista ou um objeto de dados gigante que você precisa tratar.

O filter() talvez seja a sua primeira opção porque ele cria um novo array com elementos que passam por um teste específico definido por uma função, isso já diminui a quantidade de dados que você precisa tratar.

O método filter() recebe uma função callback como argumento e esta função é chamada para cada elemento do array. Se a função callback retornar true, o elemento é incluído no novo array, simples assim.

A propósito, o array original não é alterado.

1. Filtrar um array usando múltiplas condições com o método filter()

Você pode usar o método filter() para criar um novo array que contenha apenas elementos que atendem a múltiplas condições. Por exemplo, para criar um novo array que contenha apenas números que sejam pares e maiores que 5:

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
const numerosParesMaioresQueCinco = numbers.filter(number => number % 2 === 0 && number > 5); 

No trecho de código acima, a função callback verifica se o número é par e maior que 5. Se for, o elemento é incluído no novo array numerosParesMaioresQueCinco.

E aqui o exemplo contrário, filtrar o array para incluir apenas números ímpares e menores que 5:

const oddNumbersGreaterThan5 = numbers.filter(number => number % 2 !== 0 && number < 5); 

Você pode usar o método filter() para filtrar arrays com qualquer número de condições.

2. Filtrar um array pelo tipo de dados usando o método filter()

Suponha que você tenha um array com diferentes tipos de dados, como este:

const mixedArray = [1, "string", true, {}, [], null];

Você pode usar o método filter() para criar um novo array que contenha apenas elementos de um tipo específico. Por exemplo, para criar um novo array que contenha apenas strings, você faria o seguinte:

const strings = mixedArray.filter(element => typeof element === "string");

Se o elemento for uma string, ele será incluído no novo array strings (o operador typeof retorna o tipo de dado de um valor).

Você pode usar o método filter() para filtrar arrays por qualquer tipo de dado, números, objetos, arrays e até null e undefined.

E aqui para filtrar o array para incluir apenas números:

const numbers = mixedArray.filter(element => typeof element === "number");

Ou apenas elementos que sejam objetos:

const objects = mixedArray.filter(element => typeof element === "object");

3. Filtrar um array pela propriedade de um objeto usando o método filter()

Ok, suponha que você tenha um array de objetos, como este:

const users = [
  { name: "Alice", age: 25, occupation: "Software Engineer", location: "United States" },
  { name: "Bob", age: 30, occupation: "Business Analyst", location: "Bahamas" },
  { name: "Carol", age: 20, occupation: "Analyst Programmer", location: "London" },
];

Você pode usar o método filter() para criar um novo array que contenha apenas objetos onde uma propriedade específica tenha um valor específico.

Por exemplo, para criar um novo array que contenha apenas usuários com mais de 25 anos, você faria o seguinte, usando a notação de ponto para acessar as propriedades do objeto:

const adultUsers = users.filter(user => user.age > 25);

A função callback neste exemplo verifica se a propriedade age do objeto users é maior que 25. Se for, o objeto é incluído no novo array adultUsers.

Você pode usar o método filter() para filtrar objetos por qualquer valor de qualquer propriedade. Por exemplo, você ainda pode filtrar esse array pelo nome do usuário, localização ou ocupação.

Aqui está um exemplo de como filtrar o array para incluir apenas usuários que moram nos Estados Unidos:

const usUsers = users.filter(user => user.location === "United States");

E aqui está um exemplo para incluir apenas usuários que são empregados como engenheiros de software:

const softwareEngineerUsers = users.filter(user => user.occupation === "Software Engineer");

4. Filtrar um array por propriedade de objeto aninhado usando o método filter().

Imagine que você tem uma lista de produtos, como esta:

const products = [
  {
    name: "Smart TV",
    categories: ["Electronics", "Home & Garden"],
    isOnSale: true,
  },
  {
    name: "Sunglasses",
    categories: ["Clothing", "Accessories"],
    isOnSale: false,
  },
  {
    name: "Printer",
    categories: ["Electronics", "Office Supplies"],
    isOnSale: true,
  },
];

Parece um pouco com o exemplo anterior, mas perceba que nesse array, categories é também um array, já que faz sentido um produto pertencer a mais de uma categoria.

Mas não tem problema, ainda podemos usar o método filter para filtrar os produtos de uma única categoria. Por exemplo, para filtrar o array para incluir apenas produtos que estão na categoria “Electronics”, você faria o seguinte:

const electronicProducts = products.filter(product => product.categories.includes("Electronics"));

O método includes() retorna true se o array contém o valor especificado e false caso contrário.

Ou, para filtrar o array para incluir apenas produtos da categoria “Home & Garden”:

const homeAndGardenProducts = products.filter(
  product => product.categories.includes("Home & Garden")
);

Você também pode usar o método filter() para filtrar o array por múltiplas propriedades. Por exemplo, para filtrar o array produtos para incluir apenas produtos que estão na categoria “Eletrônicos” e também estão em promoção, você faria o seguinte:

const electronicProductsOnSale = products.filter(
  product => product.categories.includes("Electronics") && product.isOnSale
);

5. Filtrar um array por expressão regular usando o método filter() do Javascript

Expressões regulares (regex) são uma ferramenta poderosa para filtrar arrays por qualquer critério que você desejar.

Você consegue encontrar padrões específicos em strings e você pode usar isso para filtrar arrays de strings, objetos ou qualquer outro tipo de array. Para filtrar um array com uma expressão regular, você só precisa passar uma função callback que usa a regex para o método filter().

Por exemplo, para encontrar qualquer string que comece com a letra A, você poderia usar a regex /^A/i:

const strings = ["Apple", "Banana", "Cat", "Dog"];

const aStrings = strings.filter(string => string.match(/^A/i));

console.log(aStrings); // ["Apple"]

Aqui estamos usando não só o método filter, mas também o método string.match() para encontrar o padrão.

Imagine que você tem uma lista de endereços de email e deseja filtrá-la para incluir apenas endereços de um domínio específico, tipo “example.com”. Você pode usar o método filter() combinado com expressões regulares para fazer isso.

const emailAddresses = ["alice@example.com", "bob@example.com", "carol@gmail.com", "dave@yahoo.com"];

const exampleEmailAddresses = emailAddresses.filter(emailAddress => emailAddress.match(/@example.com$/));

console.log(exampleEmailAddresses); // ["alice@example.com", "bob@example.com"]

A expressão regular /@example.com$/ corresponde a qualquer string que termine com “@example.com”.

Você pode usar expressões regulares para filtrar arrays por qualquer critério que quiser, por exemplo, você poderia filtrar um array de endereços de email por nome, domínio ou qualquer outra propriedade do email ou até mesmo por formato que seja válido ou inválido:

const emailAddresses = ["alice@example.com", "bob@example.com", "carol@gmail.com", "dave@yahoo.com", "invalid_email_address"];

const validEmailAddresses = emailAddresses.filter(emailAddress => emailAddress.match(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/));

console.log(validEmailAddresses); // ["alice@example.com", "bob@example.com", "carol@gmail.com", "dave@yahoo.com"]

6. Filtrar arrays de forma mais eficiente usando métodos filter() encadeados

Ok, nós vimos que é possível filtrar qualquer array usando várias condições. Outra maneira de fazer isso é encadear o método filter() a outros filtros.

Quando você usa um único método filter() com várias condições, JavaScript precisa criar um novo array para cada condição, isso pode ser ineficiente se você estiver filtrando um array grande.

Quando você usa métodos filter() encadeados, JavaScript só precisa criar um novo array. Isso porque a saída de um método filter() é usada como entrada para o próximo método filter().

Aqui está um exemplo:

const products = [
  { name: "Product A", price: 10, category: "electronics" },
  { name: "Product B", price: 20, category: "clothing" },
  { name: "Product C", price: 30, category: "electronics" },
  { name: "Product D", price: 40, category: "clothing" },
];

const cheapElectronicProducts = products.filter(
  product => product.price < 20 && product.category === "electronics"
);

Este código primeiro filtra o array products para incluir apenas produtos que custam menos de US$ 20 e que estão na categoria “eletrônicos” usando as duas condições no mesmo filter().

Agora aqui mesmo filtro, mas usando 2 métodos filter() encadeados:

const products = [
  { name: "Product A", price: 10, category: "electronics" },
  { name: "Product B", price: 20, category: "clothing" },
  { name: "Product C", price: 30, category: "electronics" },
  { name: "Product D", price: 40, category: "clothing" },
];

const cheapElectronicProducts = products
  .filter(product => product.price < 20)
  .filter(product => product.category === "electronics");

Este código também cria dois novos arrays, mas de forma mais eficiente. O primeiro método filter cria um novo array de produtos que custam menos de US$ 20. O segundo método filter usa a saída do primeiro como entrada para criar um novo array de produtos na categoria “eletrônicos”.

Encadear o método filter pode ser mais eficientes do que usar um único filter com múltiplas condições, especialmente para arrays grandes.

7. Filtrar um array encadeando outros métodos

Ok, você viu que é possível encadear dois ou mais métodos filter(), o que você ainda não viu é que você também pode encadear o método filter() com outros métodos, como map() e reduce().

Por exemplo, o código a seguir encadeia os métodos filter() e map() para obter o nome de todos os produtos eletrônicos:

const products = [
  { name: "Product A", price: 10, category: "electronics" },
  { name: "Product B", price: 20, category: "clothing" },
  { name: "Product C", price: 30, category: "electronics" },
  { name: "Product D", price: 40, category: "clothing" },
];

const cheapElectronicProductNames = products.filter(product => product.price < 20)
  .filter(product => product.category === "electronics")
  .map(product => product.name);

console.log(cheapElectronicProductNames); // ["Product A"]

Este código primeiro filtra o array products para incluir apenas produtos que custam menos de US$ 20. Em seguida, ele filtra o array para incluir apenas produtos na categoria “electronics”. Por fim, ele mapeia o array filtrado para um novo array contendo apenas os nomes de todos os produtos com valor abaixo dos US$ 20.

Você pode encadear o método filter() com qualquer outro método que recebe um array como entrada e retorna um array como saída.

Vamos testar com outras propriedades, por exemplo, pelo price:

const electronicProductPrices = products.filter(product => product.price < 20)
  .filter(product => product.category === "electronics")
  .map(product => product.price);

console.log(electronicProductPrices); // [10]

Ou aqui, vamos filtrar por idade e localização e depois, vamos contar o número de usuários que satisfazem essas condições.

const totalUsersUnder18InCalifornia = users.filter(user => user.age < 18)
  .filter(user => user.location === "California")
  .reduce((total, user) => total + 1, 0);

console.log(totalUsersUnder18InCalifornia); // 10

E pra fechar, vamos filtrar por preço, categoria e depois ordenar os produtos pelo preços.

const sortedCheapElectronicProducts = products.filter(product => product.price < 20)
  .filter(product => product.category === "electronics")
  .sort((productA, productB) => productA.price - productB.price);

console.log(sortedCheapElectronicProducts); // [{ name: "Product A", price: 10, category: "electronics" }]

8. Filtrar elementos únicos de um array usando o método filter()

Agora por último, um dos exemplos mais comuns, imagine que você tem um array de números e deseja filtrar todos os elementos duplicados. Usando o filter() você vai verificar se o elemento já está presente no array, se o elemento não estiver presente, a função callback deve retornar true. Caso contrário, a função callback deve retornar false.

Aqui está um exemplo de como fazer isso:

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

const uniqueNumbers = numbers.filter((number, index) => {
  return numbers.indexOf(number) === index;
});

console.log(uniqueNumbers); // [1, 2, 3, 4, 5, 6]

Ok, agora um pouco mais complexo, vamos tentar fazer a mesma coisa, mas agora, com um array de objetos. Por exemplo, digamos que você tem um array de usuários e deseja filtrar todos os duplicados com base na propriedade “name”.

Você pode usar a mesma abordagem do primeiro exemplo, mas precisará modificar a função callback para verificar a propriedade “nome”.

Tipo assim:

const users = [
  { name: "Alice", age: 25 },
  { name: "Bob", age: 30 },
  { name: "Carol", age: 35 },
  { name: "Alice", age: 20 },
];

const uniqueUsers = users.filter((user, index) => {
  return users.findIndex((otherUser) => otherUser.name === user.name) === index;
});

console.log(uniqueUsers); // [{ name: "Alice", age: 25 }, { name: "Bob", age: 30 }, { name: "Carol", age: 35 }]

Conclusão

De filtrar por múltiplas condições a criar padrões complexos de regex, filtrar com base em tipos de valores a se concentrar em propriedades de objetos e objetos aninhados, a gente explorou uma gama de possibilidades.

Encadear filtros e integrar outros métodos como map() e reduce() na mistura expande ainda mais seu kit de ferramentas de manipulação de arrays.

Acredito que agora você esteja melhor preparado para tratar vários dos problemas mais comuns da programação. Mas se surgir alguma duvida, deixe um comentário, te vejo na próxima!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

0 Comments