Javascript:对齐并行数组索引以避免重叠

Javascript:对齐并行数组索引以避免重叠,javascript,arrays,sorting,Javascript,Arrays,Sorting,我有一个数组列表,同一项可能出现在不同的列表中(但不在同一列表中)。 我正在尝试对数组进行排序,以便匹配的项在所有数组中具有相同的索引。 我也在尽可能地填补空白,但如果某些位置没有定义,那也没关系 条件 所有重复都是连续的,因此如果一个元素是重复的,那么前一个数组中肯定有一个副本 每个阵列中每个项目只能出现一次(重复项仅在不同的阵列中) foo数组可能具有不同的长度 foo数组总是存在的,在最坏的情况下它是空的 只要目标完成,foo数组中的顺序就不相关 包装器数组无法排序 输入 constmyw

我有一个数组列表,同一项可能出现在不同的列表中(但不在同一列表中)。 我正在尝试对数组进行排序,以便匹配的项在所有数组中具有相同的索引。 我也在尽可能地填补空白,但如果某些位置没有定义,那也没关系

条件

  • 所有重复都是连续的,因此如果一个元素是重复的,那么前一个数组中肯定有一个副本
  • 每个阵列中每个项目只能出现一次(重复项仅在不同的阵列中)
  • foo数组可能具有不同的长度
  • foo数组总是存在的,在最坏的情况下它是空的
  • 只要目标完成,foo数组中的顺序就不相关
  • 包装器数组无法排序
  • 输入

    constmywrapper[
    {foo:[]},
    {foo:[A',B',C',D']},
    {foo:['X','A','E','C']},
    {foo:['X','F','C','G','H']},
    {foo:['C']}
    ];
    
    所需输出

    constmywrapper[
    {foo:[]},
    {foo:['B','A','C','D']},
    {foo:['X','A','C','E']},
    {foo:['X','F','C','G','H']},
    {foo:[未定义,未定义,'C']}
    ];
    
    有没有一个简洁的方法来实现这一点

    我的尝试是,从右侧排序并使用tmp变量交换项目。 这似乎不起作用,因为下面的位置有时会移动前一个项目,使前一个迭代中的顺序集混乱

    let-tmp;
    myWrapper.forEach((项目,包装索引)=>{
    item.foo.forEach((currentFoo,fooIndex)=>{
    //在上一个foo中搜索匹配项
    if(myWrapper[wrapperIndex-1]){
    const prevFoo=myWrapper[wrapperIndex-1].foo;
    常量prevIndex=prevFoo.indexOf(项目);
    如果(prevIndex>=0&&prevIndex!==fooIndex){
    tmp=prevFoo[fooIndex];
    prevFoo[fooIndex]=prevEvents[prevIndex];
    prevFoo[prevIndex]=tmp;
    }
    }
    });
    });
    
    编辑:问题还在于循环对单个项(实际上是对象,我使用字符串来简化)执行其他操作,因此无法从右侧移动(当前项)

    使用2嵌套*ngFor通过角度渲染输出,因此最终结果必须保持此数组结构

    编辑

    这是一个更简单的解决方案,使用与我原始答案相同的重复映射,然后使用简单的交换算法将重复值移动到相应的索引中

    const myWrapper=[
    {foo:[]},
    {foo:[A',B',C',D']},
    {foo:['X','A','E','C']},
    {foo:['X','F','C','G','H']},
    {foo:['C']}
    ];
    //查找重复项并创建索引映射
    让
    新的一套,
    dupeMap={},d=0;
    for(myWrapper的常量{foo}){
    for(foo的常数x){
    看到了。has(x)
    ?dupeMap[x]??=d++
    :见。加(x);
    }
    }
    //将副本交换到适当的索引中
    for(myWrapper的常量{foo}){
    让
    i、 j,温度;
    对于(i=0;iconsole.log(`foo:[${foo.map(e=>e??).join(','}]}')
    
    。作为控制台包装{max height:100%!important;top:0;}
    最后,我从@pilchard的工作开始,想出了一个更简单的解决方案

    使用简单字符串

    函数arrangeParallelItems(包装器){
    //从第二个元素开始,这样我们就可以回头看
    wrapper.slice(1).forEach((项目,项目索引)=>{
    设i=-1,
    杜佩因,
    tmp;
    而(++i-1&&dupeIndex!==i){
    tmp=item.foo[i];
    item.foo[i]=item.foo[dupeIndex];
    项目foo[dupeIndex]=tmp;
    我--;
    }
    }
    });
    }
    常量myWrapper=[
    {foo:[]},
    {foo:[A',B',C',D']},
    {foo:['X','A','E','C']},
    {foo:['X','F','C','G','H']},
    {foo:['C']}
    ];
    排列平行项(myWrapper);
    myWrapper.forEach({foo})=>
    console.log(`{foo:[${foo.map(e=>e??”).join(',')}]}`)
    
    )
    您的重构依赖于从一个数组到下一个数组的重复数据的连续性,以保持一致的索引(因为它只查看一个数组的后面)。如果中断此连续性,索引将重置

    我复制了你的代码片段并添加了一个“断开”的短数组。
    函数arrangeParallelItems(包装器){
    //从第二个元素开始,这样我们就可以回头看
    wrapper.slice(1).forEach((项目,项目索引)=>{
    设i=-1,
    杜佩因,
    tmp;
    而(++i-1&&dupeIndex!==i){
    tmp=item.foo[i];
    item.foo[i]=item.foo[dupeIndex];
    项目foo[dupeIndex]=tmp;
    我--;
    }
    }
    });
    }
    常量myWrapper=[
    {foo:[]},
    {foo:[A',B',C',D']},
    {foo:['H']},
    {foo:['X','A','E','C']},
    {foo:[A',B',C',D']},
    {foo:['F','C','G','H','X']},
    {foo:['C']}
    ];
    排列平行项(myWrapper);
    myWrapper.forEach({foo})=>
    console.log(`{foo:[${foo.map(e=>e??”).join(',')}]}`)
    )

    作为控制台包装{max height:100%!important;top:0;}
    您能描述所需的输出吗?对我来说,这看起来不是很有条理。但是为什么最后的“X”不是呢?第一个数组是否也可以是
    ['D','A','C','B']