提高forEach迭代的性能



我正在尝试将较大的数组(10K(记录与较小的数组(2K(记录进行筛选。

使用此代码几乎需要5秒钟才能完成。

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 inventory

我使用forEach而不是filter(在90毫秒时速度更快(的原因是我在同一(10K(阵列中寻找两个不同的项目。即使我使用了filter,我仍然需要将主数组和辅助数组中的数据附加到包含它们所有数据的最终对象。

我的最佳选择是什么来优化它,使它不会那么慢,但满足我对包括项目详细信息和订单详细信息的最终阵列的要求?

假设您的三个列表具有以下结构:

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 }];

第一个想法:通过localOrdersonlineOrders比通过allItems便宜得多,后者可能是一个大得多的列表。此外,在当前代码中,您正在迭代最长列表中的EACH对象,对于这些对象中的每一个,您都在迭代整个localOrdersonlineOrders。因此,最好反其道而行之,从较短的列表开始。

对于每个本地订单,您希望在具有allItems.find(item => item.id===localOrder.itemId)的大列表中找到相应的项目。与.forEach()不同,.find()一找到元素就停止遍历数组,这为您节省了很多周期。

所以你可以从这样的东西开始:

let inventory = localOrders.map(localOrder => ({
item : allItems.find(item => item.id===localOrder.itemId),
order : localOrder,
type: 'local',
}))

这是针对本地订单,现在是在线订单:

inventory = inventory.concat(onlineOrders.map(onlineOrder => ({
item : allItems.find(item => item.id===onlineOrder.itemId),
order : onlineOrder,
type: 'online',
})))

它很有效,但有点笨拙,因为您要重复两次几乎相同的代码。如果你有第三种类型的订单,你会重复相同的代码三次、四次,等等。所以,一种更聪明的做法是把订单放在一个对象中,这样你就可以拥有你想要的任意类型的订单而不重复自己,比如:

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);

最新更新