Como filtrar QUALQUER array de objetos no JavaScript
Olá pessoas!
Recentemente me deparei com um problema no meu estágio, onde eu precisava realizar uma filtragem de um array de objetos, dado um determinado input.
Mesmo depois de inúmeras pesquisas, não encontrei um método que atendia minha necessidade, pois, nenhum atuava de maneira genérica. Entretanto, as pesquisas me fizeram aprender o suficiente para que eu mesmo desenvolve-se uma solução.
Dessa maneira, gostaria de compartilhar com vocês o meio de utilizei prara isso!
Definindo estrutura de dados
Primeiro de tudo, é necessário definir o tipo de estrutura de dados mais genérica que iremos trabalhar.
No meu caso, eu recebi um array com vários objetos contendo informações pessoais dos usuários.
// Array de Objetos
const arr = [
{
nome: "Xandy",
idade: 21,
nacionalidade: "Brasil",
cargo: "Programador"
},
{
nome: "Marcela",
idade: 21,
nacionalidade: "Portugal",
cargo: "Engenheira de Software"
},
{
nome: "João Victor",
idade: 35,
nacionalidade: "Espanha",
cargo: "Arquiteto"
},
{
nome: "Sophia",
idade: 29,
nacionalidade: "Brasil",
cargo: "Astronauta"
},
];
Criando a função
A partir de uma entrada, eu preciso encontrar qualquer resultado semelhante em cada item de cada um dos objetos do array.
Para isso, três funções básicas do JavaScript serão utilizadas, sendo elas: include, map e filter.
// Função para filtrar
const Filter = (event) => {
return arr.filter(obj => {
return Object.values(obj).map(item => {
return (item === null ? "" : item.toString().includes(event.target.value.toString()));
}).includes(true);
});
}
Explicação
Para melhor compreensão do que foi realizado, vamos dissecar a função de dentro para fora.
Include
Para isso, é necessário entender o método mais interno da função: o include.
O método includes() determina se um array inclui um determinado valor entre suas entradas, retornando true ou false conforme apropriado.
Dessa maneira, é possível analisar o valor de um item do objeto e comparar com a entrada dada pelo usuário, retornando um boolean para a avaliação feita.
Caso o valor seja nulo, ele retorna uma string vazia e, caso exista um valor no item analisado, o mesmo é convertido para uma string e comparado com o input do usuário, retornando true se obtiverem semelhança.
return (item === null ? "" : item.toString().includes(event.target.value.toString()));
Map
Posto isso, é necessário analisar cada um dos itens do objeto. Para isso, realiza-se um map nos valores do objeto, fazendo com que a função apresentada anterior seja executada para cada um.
O método map() cria uma nova matriz preenchida com os resultados da chamada de uma função fornecida em cada elemento da matriz de chamada.
return Object.values(obj).map(item => {
return (item === null ? "" : item.toString().includes(event.target.value.toString()));
}).includes(true);
É interessante notar que, no final da função map(), também é realizado uma verificação com o include. O motivo será explicado a partir da próxima e última função.
Filter
Após realizar a verificação em cada um dos itens de um objeto, agora fica mais simples. É necessário filtar os objetos que possuem um item semelhante ao input do usuário. Sendo assim, a função filter resolve o problema.
O método filter() cria uma cópia superficial de uma parte de uma determinada matriz, filtrada apenas para os elementos da matriz fornecida que passam no teste implementado pela função fornecida.
Assim, caso algum dos objetos possua um item semelhante ao input do usuário, ele irá retornar um array com pelo meno um true, graças ao include dentro do objeto. Em seguida, um segundo include é realizado nesse array (aquele citado no método map), checando se existe algum valor true dentro do mesmo. Caso exista um valor true, o objeto passa no teste do filter e é salvo dentro do novo array.
Dessa maneira, obtêmos nossa função com toda sua lógica aplicada:
return arr.filter(obj => {
return Object.values(obj).map(item => {
return (item === null ? "" : item.toString().includes(event.target.value.toString()));
}).includes(true);
});
Aqui podemos ver um exemplo da utilização do filtro no array de objetos apresentado no inicio do artigo, mostrando que foi retornado os dois objetos que possuem Brasil como nacionalidade.
O código completo utilizado pode ser encontrado no meu repositório no GitHub
Considerações finais
É importante lembrar que, existem inúmeras maneiras de se solucionar um mesmo problema. Essa foi a solução que eu consegui encontrar no tempo que me foi dado, e ela me serviu bem.
Se você tem ideia de outra maneira mais eficiente para realizar a mesma tarefa, deixa aí nos comentários que eu vou adorar aprender!!!
Espero ter contribuido de alguma maneira.
Abraços! 🐢