Estoy intentando filtrar registros de una matriz más grande (10K) contra una matriz más pequeña (2K).
El uso de este código tarda casi 5 segundos en completarse.
let inventory = [] allItems.forEach((item) => { localOrders.forEach((order) => { if (item.id === Number(order.itemId)) { inventory.push({ item, order, type: 'local', }) } }) onlineOrders.forEach((order) => { if (item.id === Number(order.itemId)) { inventory.push({ item, order, type: 'online', }) } }) }) return inventoryLa razón por la que uso forEach en lugar de filter (que es mucho más rápido a 90 ms) es que estoy buscando dos elementos diferentes en la misma matriz (10K). Incluso si usara el filtro, aún necesitaría adjuntar los datos de la matriz primaria y secundaria a un objeto final que incluya todos los datos para ellos.
¿Cuál es mi mejor opción para optimizar esto para que no sea tan lento, pero satisfaga mi requisito de una matriz final que incluya los detalles del artículo y los detalles del pedido?
Suponiendo que sus tres listas tengan esta estructura:
const allItems = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }, { id: 7 }, { id: 8 }, { id: 9 }]; const localOrders = [{ itemId: 3 }, { itemId: 7 }]; const onlineOrders = [{ itemId: 5 }, { itemId: 7 }]; Primera idea: es mucho más barato pasar por localOrders y onlineOrders que por allItems , que puede ser una lista MUCHO más grande. Además, en su código actual, está iterando CADA objeto en la lista más larga, y para cada uno de estos objetos, está iterando la totalidad de localOrders y onlineOrders . Por lo tanto, es una buena idea hacer lo contrario y comenzar con las listas más cortas.
Para cada pedido local, desea encontrar el artículo correspondiente en la lista grande con allItems.find(item => item.id===localOrder.itemId) . A diferencia .forEach() , .find() deja de recorrer la matriz tan pronto como encuentra el elemento, lo que le ahorra muchos ciclos.
Así que puedes empezar con algo como esto:
let inventory = localOrders.map(localOrder => ({ item : allItems.find(item => item.id===localOrder.itemId), order : localOrder, type: 'local', }))Eso es para los pedidos locales, ahora los pedidos en línea:
inventory = inventory.concat(onlineOrders.map(onlineOrder => ({ item : allItems.find(item => item.id===onlineOrder.itemId), order : onlineOrder, type: 'online', })))Funciona, pero es un poco torpe, porque estás repitiendo prácticamente el mismo código dos veces. Y si tiene un tercer tipo de orden, repetirá el mismo código tres veces, cuatro veces, etc. Entonces, una forma más inteligente de hacer las cosas es poner las órdenes en un objeto, para que pueda tener tantos tipos de ordena como quieras sin repetirte, algo como esto:
const allItems = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }, { id: 7 }, { id: 8 }, { id: 9 }]; const orders = { "local" : [{ itemId: 3 }, { itemId: 7 }], "online" : [{ itemId: 5 }, { itemId: 7 }], "delayed" : [{ itemId: 8 }] } let inventory = []; Object.keys(orders).forEach( type => { // type=="local", type=="online" inventory = inventory.concat(orders[type].map(localOrder => ({ item : allItems.find(item => item.id===localOrder.itemId), order : localOrder, type, }))) }) console.log(inventory);