我需要对非常大(超过200k个元素)的对象数组执行2个过滤器,因此我希望我的代码在javascript中尽可能快。
第一个过滤器很简单,因为我只需要删除为空(null)的元素:
let validArr = originalArr.filter(el => { return el != null });
第二个过滤器将检查validArr[i].name
是否等于其他数组的元素之一。目前我是这样的:
for(let i = 0, l = validArr.length; i < l; i++) {
if (findInArray(validArr[i].name, otherArr)) {
finalArr.push({
name: validNpc[i].nick,
id: validNpc[i].id
});
}
}
const findInArray = (val, arr) => {
for(let i = 0, l = arr.length; i < l; i++) {
if(arr[i] === val) return true;
}
return false;
};
在循环中,我进行了微优化,但是我想重构O(n ^ 2),但我不知道如何。
答案 0 :(得分:6)
将otherArr转换为Set,然后查找将使用O(1),整个循环为O(n):
const names = new Set(otherArr);
const result = validArr
.filter(it => names.has(it.name))
.map(({ nick, id }) => ({ name: nick, id }));
答案 1 :(得分:2)
您可以使用时间复杂度为O(1)的Set
和has
方法
otherArr = new Set(otherArr);
for(let i = 0, l = validArr.length; i < l; i++) {
if (findInArray(validArr[i].name, otherArr)) {
finalArr.push({
name: validNpc[i].nick,
id: validNpc[i].id
});
}
}
const findInArray = (val, arr) => {
return arr.has(val)
};
您可以使用forEach()
otherArr = new Set(otherArr)
const finalArr = [];
validArr.forEach(x => {
if(otherArr.has(x.name)){
finalArr.push({ name:x.nick, id:x.id })
}
})