数组过滤器-摆脱O(n ^ 2)

时间:2019-05-29 11:31:14

标签: javascript arrays filter

我需要对非常大(超过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),但我不知道如何。

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)的Sethas方法

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