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 objeto usersIndexado com o ID do usuário (elemento.created_by). Isso permite um acesso direto aos usuários com base no seu ID, 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

Link para executar o código: https://www.sololearn.com/en/compiler-playground/cPdNJ17Ne15W