JavaScript - Formas de realizar buscas em listas muito grandes
Já passou pela situação onde precisava realizar um filtro em uma lista muito grande ? Talvez essa ideia possa te ajudar. Aqui esta um exemplo básico de como aplicar índices em JavaScript.
const users = [
{ age: 37, name: "Moore Hampton" },
{ age: 25, name: "Stephanie Clayton" },
{ age: 30, name: "Pratt Cash" },
{ age: 21, name: "Kenya Gould" },
{ age: 38, name: "Dodson Romero" },
{ age: 34, name: "Weiss Bush" },
{ age: 27, name: "Myrtle Hatfield" },
{ age: 36, name: "Bertie Spencer" },
{ age: 35, name: "Fisher Arnold" },
{ age: 24, name: "Susie Hebert" },
{ age: 37, name: "Beth Lloyd" },
{ age: 24, name: "Keisha Gilliam" },
{ age: 38, name: "Rachel Schultz" },
{ age: 25, name: "Jeanine Flores" },
{ age: 27, name: "Jensen Maddox" },
{ age: 24, name: "Callie Crawford" },
{ age: 22, name: "Campbell Chase" },
{ age: 39, name: "Collins Mercado" },
{ age: 38, name: "Cantu Mcclure" },
{ age: 37, name: "Duffy Buckley" },
{ age: 36, name: "Suzette Navarro" },
{ age: 40, name: "Aida Murray" },
{ age: 35, name: "Alyssa Humphrey" }
];
const usersByAge = {};
users.forEach((user) => {
if (!usersByAge[user.age]) {
usersByAge[user.age] = [];
}
usersByAge[user.age].push(user);
});
// Usuários com 35 anos
console.log(usersByAge[35]);
// Usuários com 37 anos
console.log(usersByAge[37]);
Já passou por um problema assim ? Compartilhe sua solução.
Gosto muito de criar índices para essa solução, tenho uma função bem simples que me ajuda com isso:
function createIndex<T>(list: T[], key: keyof T) {
const DEFAULT_INDEX = {} as Record<string, T[]>;
return list.reduce((index, item) => {
const indexKey = String(item[key] as keyof typeof index);
const existKey = Boolean(index[indexKey]);
if (!existKey) {
index[indexKey] = [];
}
index[indexKey].push(item);
return index;
}, DEFAULT_INDEX);
}
Pra criação de índices experimente usar Map ao invés de um Object. O tipo Map prevê a criação de novos índices, exclusão, verificação se a chave existe ou não, etc... Para esse tipo de tarefa é mais apropriada do que Object e DESCONFIO (não fiz testes pra saber) que vai ter melhor performance e menos consumo de memória.
hummm. Se chegar ao ponto que você precisa fazer isso em uma lista grande, não seria melhor pedir isso ja organizado pro backend? Fazer um foreach e depois dar um console log. entao pq nao logar já no momento do foreach? Mesmo que você faça im foreach ou reduce ou qqr coisa. Só esse processamento ja é pesado se a lista for muito grande. A não ser que você receber um xls assim, mas ai vale a pena processar todo ele primeiro e criar as funções de consulta. Enfim. antes de pensar em uma solução para esse problema uma das formas é pensar porque você tem o problema em si e tentar resolver isso e não só o que esta na sua frente.
Acho que não é a resposta que esperava, mas enfim, pra pensar. :)
Vale lembrar que isso só vale a pena se tiver um array muito grande e forem feitas muitas buscas. Afinal, há um custo inicial para criar o índice de usuários por idade (tanto em tempo quanto em memória), e nem sempre compensa.
Se você só precisa buscar uma ou duas idades, por exemplo, aí um for
simples no array é mais rápido. Fiz uns testes usando o Benchmark.js e só a partir de 10 buscas (ou seja, buscar por 10 idades diferentes) começou a valer a pena. Com menos que isso, fazer vários for
no array (um para cada idade a ser buscada) foi mais rápido. Testando no JSBench.ME, os resultados foram similares: com poucas buscas, o for
simples é mais rápido, e a partir de umas 12 buscas, a sua solução se tornou mais rápida.
Claro que os números exatos podem variar caso a caso, e depende muito do ambiente, dos dados e das buscas feitas. E se forem arrays muito pequenos e/ou poucas buscas, a diferença será irrisória e até imperceptível.
De qualquer forma, temos aqui um exemplo do clássico trade-off (em bom português: "cada escolha, uma renúncia") de tempo e espaço: o programa pode rodar mais rápido, o que compensa o uso extra de memória. Mas tem casos em que não haverá esse ganho. É bom saber que você pode usar essa solução caso precise, mas também é importante saber quando não precisa :-)
Mano, que dica top viu, me ajudou bastante. A criação do "problema", a forma da solução, os nomes simples e em inglês, muito show viu. Parabéns, thanks!