Buscando elementos em um Array com JavaScript
Neste exemplo, iremos utilizar uma lista com 1000 elementos e depois procurar por um item específico para popular um objeto.
users
: uma lista vazia que será preenchida com objetos de usuário, cada um contendo um id
e um name
gerado aleatoriamente.
lista
: uma lista vazia que será preenchida com objetos, cada um contendo um id
, um name
gerado aleatoriamente e um created_by
, que é um número aleatório representando o ID
do usuário que criou o item.
Criando uma array de usuários para o exemplo
let users = [];
for (let i = 999; i>= 0; i--) {
users[i] = {
id: i, // id do usuário
name: Math.random().toString(), // número aleatório, só de exemplo
}
};
console.log(users);
/*
[
{ id: 0, name: '0.426235872591598' },
{ id: 1, name: '0.823170310218656' },
{ id: 2, name: '0.09842298865230625' },
{ id: 3, name: '0.7783152759039933' },
{ id: 4, name: '0.0028401449771886522' },
...
]
*/
Lista de elementos criada por um usuário
const lista = [];
// inserindo na lista um objeto com id, name e created_by
for (let i = 0; i < 10000; i++) {
lista[i] = {
id: i,
name: Math.random(),
created_by: Math.floor(Math.random() * 10000) // número aleatório, só de exemplo
}
};
console.log(lista);
/*
[
{ id: 0, name: 0.9564765360092851, created_by: 787 },
{ id: 1, name: 0.21613002333924802, created_by: 7 },
{ id: 2, name: 0.7642346570109826, created_by: 110 },
{ id: 3, name: 0.2316052787206666, created_by: 281 },
{ id: 4, name: 0.6850302052860899, created_by: 379 },
...
]
*/
Uma nova lista igual à anterior, porém contendo a propriedade created_by_user
// objeto com created_by_user usando o método find
console.time('usando find');
const conUserFind = lista.map(elemento => {
return {
...elemento, // retornando a cópia do elemento
created_by_user: users.find(u => u.id === elemento.created_by)
}
});
console.timeEnd('usando find');
// usando find: 31.566ms
Alternativa para melhorar a performance
Criando um objeto em que as propriedades são iguais à propriedade que queremos indexar: o id do usuário. A propriedade
created_by_user
é preenchida diretamente acessando o objetousersIndexado
com oID
do usuário(elemento.created_by)
. Isso permite um acesso direto aos usuários com base no seuID
, sem a necessidade de percorrer a lista de usuários novamente.
// indexar os usuários usando o método reduce
const usersIndexado = users.reduce((acc, el) => {
acc[el.id] = el
return acc
}, {})
console.log(usersIndexado);
/*
{
'0': { id: 0, name: '0.779847818497515' },
'1': { id: 1, name: '0.32584753910554465' },
'2': { id: 2, name: '0.19885950823939602' },
'3': { id: 3, name: '0.14249609459294854' },
'4': { id: 4, name: '0.3774917744552999' },
...
}
*/
Obtendo os usuários usando o index
console.time('usando index');
const conUserIndex = lista.map(elemento => {
return {
...elemento,
created_by_user: usersIndexado[elemento.created_by]
}
});
console.timeEnd('usando index');
// usando find: 31.146ms
// usando index: 6.221ms
Conclusão
O resultado final mostra uma melhoria significativa de desempenho ao usar o acesso direto por índice em comparação com o método find
. O tempo de execução usando o acesso direto por índice (usando index)
é consideravelmente menor do que o tempo usando find
. Isso demonstra a eficiência da otimização por meio do uso de um objeto indexado.
Outras alternativas
- lodash https://www.geeksforgeeks.org/lodash-_-keyby-method/
- ramdajs https://ramdajs.com/docs/#indexBy
Link para executar o código: https://www.sololearn.com/en/compiler-playground/cPdNJ17Ne15W