繁体   English   中英

JavaScript Array.filter 唯一性而不是阻止 UI

[英]JavaScript Array.filter uniqes and not block the UI

我有一个特定的用例,其中一些验证逻辑必须在 UI 中发生(出于各种业务原因[...])。 该数组可能包含多达几十个或多达几十万个项目 (1-400K)。 前端是基于 Angular 的。

第一步是检查重复项(并将它们存储在另一个数组中[...])。 这是通过以下方式完成的:

validateTargets(targets: string[]): ValidationResultObject[] {

    let result: ValidationResultObject[];
    let dups: string[] = [];

    var uniques = targets.filter( (item,index) => {
        if (targets.indexOf(item) === index) {
        return targets.indexOf(item) === index
        }
        else {
            dups.push(targets[index])
        }
    }

    //other validation logic goes here

    return result;
}

问题是当它针对 50K 以上的任何内容运行时,明显的 UI 冻结。 目前,我已经在setTimeout中的另一个函数中作为回调放在上面,以至少允许 UI 在页面挂起时运行微调器 :)

我已经看到人们建议如何设计代码以允许 UI 具有响应性(或至少重新绘制)的几种方式; 但是,我的情况有点棘手,因为我要处理重复项。

我正在考虑将数组分解为块并在setTimeout (用于 UI)内的循环中在Array.filter部分上方运行,但我后来无论如何都需要将这些块与它们自己进行比较,因此它只会延长逻辑! 我觉得对员工进行试验不太舒服,因为组织中的浏览器不支持这些浏览器。

有谁知道如何解决这个问题? 不,不可能将其移动到后端:(

问候

您可以更有效地过滤掉重复项:

let filtered = targets.reduce((result, item) => {
  result[item] = 1;
  return result;
}, {});
let noDuplicates = Object.keys(filtered);

这使得一次遍历数组,并利用属性名称查找的内部效率超过.indexOf()的顺序搜索。 对于具有大量元素的初始数组,这应该在相对较短的时间内运行。

我从未遇到过这种情况,但我想问一下您是否在 javascript 中使用了Set类型,因为它在内部删除了重复项,并且比过滤JS Set vs Array更高效,如果您的浏览器不支持 Set,您仍然可以使用 polyfill。

您可以使用异步函数来处理此数量的数据。 当它完成时,以结果为参数调用回调以在完成后继续正常流程。

async validateTargets(targets: string[], callback: function): {
 //...Logic
 callback(result)
}

此外,要删除重复项,您可以使用

[...new Set(items)]

注意:这仅在 Items 数组仅包含原始值时才有效

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM