Javascript 消除大量阵列重复数据的有效方法

Javascript 消除大量阵列重复数据的有效方法,javascript,arrays,Javascript,Arrays,我有一个非常大的数组(大约960799个条目,或者可能更大)。我需要将其处理为一个新阵列,以便: 每个子数组不包含重复项 主数组不包含重复的子数组 问题是,“重复子数组”必须包含具有不同顺序的相同值的数组。换句话说,如果我有这些子数组: [[1,2,3],[1,2,3],[3,1,2]] 它们都被认为是重复的,只保留一个(其中任何一个都不重要;我只保留了第一个;如果所选子数组的顺序实际上不匹配也可以,即如果子数组中元素的顺序在处理过程中发生变化) 我尝试的解决方案是,根据子数组的重复数据消除、排

我有一个非常大的数组(大约960799个条目,或者可能更大)。我需要将其处理为一个新阵列,以便:

  • 每个子数组不包含重复项
  • 主数组不包含重复的子数组
  • 问题是,“重复子数组”必须包含具有不同顺序的相同值的数组。换句话说,如果我有这些子数组:

    [[1,2,3],[1,2,3],[3,1,2]]

    它们都被认为是重复的,只保留一个(其中任何一个都不重要;我只保留了第一个;如果所选子数组的顺序实际上不匹配也可以,即如果子数组中元素的顺序在处理过程中发生变化)

    我尝试的解决方案是,根据子数组的重复数据消除、排序和使用分隔符连接,将所有子数组映射为字符串。然后我对最后一个数组进行重复数据消除,然后将它们映射回具有拆分的数组。这是可行的,但过程非常缓慢。单次扫描需要30秒以上的时间,而且由于我最终处理的阵列可能会成倍增大,这是不可接受的。我需要一个更有效的算法

    下面是我现在使用的代码,速度很慢(
    ret
    是输入数组):

    谁能帮我更有效地得到同样的结果?谢谢

    编辑

    更详细地说,我通过计算一些字符串输入的幂集来获得这些大量的输入数组。这就是代码;如果有可能首先阻止它产生重复条目,我认为这也会很好地工作:

    // Calculate the Cartesian product of set s
    function cart(s) {
        return s.reduce((acc, val) => {
            return acc.map((x, i) => {
                return val.map(y => {
                    return x.concat([y]);
                });
            }).flat();
        }, [[]]);
    }
    
    // Use the Cartesian product to calculate the power set of set s
    function pset(s) {
        let ret = [];
        for (let i = 0; i < s.length; ++i) {
            const temp = [];
            for (let j = 0; j <= i; ++j) {
                temp.push([].concat(s));
            }
            ret = ret.concat(cart(temp));
        }
        return ret;
    }
    
    //计算集合s的笛卡尔积
    功能车{
    返回s.reduce((acc,val)=>{
    返回acc.map((x,i)=>{
    返回val.map(y=>{
    返回x.concat([y]);
    });
    }).flat();
    }, [[]]);
    }
    //使用笛卡尔积计算集合s的幂集
    功能pset(s){
    设ret=[];
    对于(设i=0;i对于(假设j=0;j),您可以生成无重复项的功率集

    函数pset(数组){
    功能iter(索引、温度){
    如果(索引>=array.length){
    温度长度和结果推送(温度);
    返回;
    }
    国际热核实验堆(指数+1,温度混凝土(阵列[指数]);
    iter(指数+1,温度);
    }
    var结果=[];
    iter(0,[]);
    返回结果;
    }
    console.log(pset(['a','b','c']);

    .as console wrapper{max height:100%!important;top:0;}
    考虑到我无法使用真实数据执行基准测试,我无法验证这种方法对您的用例来说快了多少,但是通过对
    循环使用基本
    ,并尽可能方便地避免使用函数代码,我得出以下结论:

    const ret=[[1,2,3]、[1,2,3]、[3,1,2]、[1,4,5]、[4,1,5];
    函数升序(a,b){
    //适用于字符串和数字
    返回-(ab);
    }
    功能提升2D(a,b){
    常数长度=a.长度;
    常量长度=b.长度;
    常量长度=数学最小值(长度、混合度);
    for(设i=0;iconsole.log(output);
    EDIT:Nevermind,我的实现没有基准。速度较慢。这是由于
    JSON.parse
    JSON.stringify
    的底层实现,以及
    数组#排序的默认算法

    由于您正在寻找最先进的性能,因此很难获得一个优雅的解决方案。如果您使用
    object.create(null)
    实例化一个对象,则可以将O(1)的开销降至最低插入。它创建一个没有原型的POJO。您也不需要在
    对象的
    in
    循环中签入
    ,因为没有原型可搜索

    const ret=[[],[1,2,3],[3,1,2],[1,4,5],[4,1,5];
    const hashMap=Object.create(null)
    函数createUniqArraysOfPrimitiveArrays(ret){
    for(设i=0;iconsole.log(createUniqArraysOfPrimitiveArrays(ret))
    我知道你的问题是关于重复数据消除的,但是你的阵列和子阵列首先是如何生成的?在效率方面,如果可能的话,最好是在一开始就不生成重复的阵列和子阵列。看看这个答案,了解一些想法@PatrickRoberts,它们基本上被计算为一个值的输入数组。基本上,我有一个计算数组笛卡尔积的函数。我在越来越长的相同输入数组集上运行该函数,重复1到N次(N=输入的长度)并将结果连接在一起。这确实会产生一个幂集,但现在我需要消除该结果的重复,因为较小迭代的乘积与较大迭代的乘积重叠。我将看看是否可以修改幂集代码,以首先防止重复。@PatrickRoberts我已将幂集计算代码添加到OP.I中我试图修改它以防止生成重复项,结果却从最终输出中删除了合法的唯一值;我不同意
    // Calculate the Cartesian product of set s
    function cart(s) {
        return s.reduce((acc, val) => {
            return acc.map((x, i) => {
                return val.map(y => {
                    return x.concat([y]);
                });
            }).flat();
        }, [[]]);
    }
    
    // Use the Cartesian product to calculate the power set of set s
    function pset(s) {
        let ret = [];
        for (let i = 0; i < s.length; ++i) {
            const temp = [];
            for (let j = 0; j <= i; ++j) {
                temp.push([].concat(s));
            }
            ret = ret.concat(cart(temp));
        }
        return ret;
    }