gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 23:38:37 24 4
gpt4 key购买 nike

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

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

  • 输入
    const myWrapper [
    { foo: [] },
    { foo: ['A', 'B', 'C', 'D'] },
    { foo: ['X', 'A', 'E', 'C'] },
    { foo: ['X', 'F', 'C', 'G', 'H'] },
    { foo: ['C'] }
    ];
    所需输出
    const myWrapper [
    { foo: [] },
    { foo: ['B', 'A', 'C', 'D'] },
    { foo: ['X', 'A', 'C', 'E'] },
    { foo: ['X', 'F', 'C', 'G', 'H'] },
    { foo: [undefined, undefined, 'C'] }
    ];
    有没有一种巧妙的方法来实现这一目标?
    我的尝试,从右侧排序并使用 tmp 变量来交换项目。
    这似乎效果不佳,因为以下位置有时会移动先前的项目,从而弄乱先前迭代中设置的顺序。
        let tmp;
    myWrapper.forEach((item, wrapperIndex) => {
    item.foo.forEach((currentFoo, fooIndex) => {
    // Search for match in the previous foo
    if(myWrapper[wrapperIndex - 1]) {
    const prevFoo = myWrapper[wrapperIndex - 1].foo;
    const prevIndex = prevFoo.indexOf(item);
    if (prevIndex >= 0 && prevIndex !== fooIndex) {
    tmp = prevFoo[fooIndex];
    prevFoo[fooIndex] = prevEvents[prevIndex];
    prevFoo[prevIndex] = tmp;
    }
    }
    });
    });
    编辑:问题还在于循环对单个项目(实际上是对象,我使用字符串来简化)执行其他操作,所以我不能从右侧移动(当前项目)。

    The output is rendered via Angular using 2 nested *ngFor so the final result has to maintain this array structure.

    最佳答案

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

    const myWrapper = [
    { foo: [] },
    { foo: ['A', 'B', 'C', 'D'] },
    { foo: ['X', 'A', 'E', 'C'] },
    { foo: ['X', 'F', 'C', 'G', 'H'] },
    { foo: ['C'] }
    ];

    // find dupes and create map of indexes
    let
    seen = new Set,
    dupeMap = {}, d = 0;
    for (const { foo } of myWrapper) {
    for (const x of foo) {
    seen.has(x)
    ? dupeMap[x] ??= d++
    : seen.add(x);
    }
    }

    // swap duplicates into appropriate indexes
    for (const { foo } of myWrapper) {
    let
    i, j, temp;
    for (i = 0; i < foo.length; i++) {
    j = dupeMap[foo[i]];
    if (j !== undefined && j !== i) {
    temp = foo[i];
    foo[i] = foo[j];
    foo[j] = temp;
    i--;
    }
    }
    }

    myWrapper.forEach(({ foo }) => console.log(`{foo: [${foo.map(e => e ?? ' ').join(', ')}]}`));
    .as-console-wrapper { max-height: 100% !important; top: 0; }


    原答案
    这是一个避免排序的相当简单的解决方案。它首先创建一个对象,其中包含重复值的 Prop 和最终数组中该值的预期索引作为值。
    然后它遍历每个 foo数组通过重复映射中的索引将重复值放置在临时数组中,并将唯一值推送到第二个临时数组。
    在退出之前,它会尝试从唯一数组中的任何值回填临时重复数组中的漏洞。
    这会改变 myWrapper阵列到位。

    const myWrapper = [
    { foo: [] },
    { foo: ['A', 'B', 'C', 'D'] },
    { foo: ['X', 'A', 'E', 'C'] },
    { foo: ['X', 'F', 'C', 'G', 'H'] },
    { foo: ['C'] }
    ];

    // find dupes and create map of indexes
    let
    seen = new Set,
    dupeMap = {}, d = 0;
    for (const { foo } of myWrapper) {
    for (const x of foo) {
    seen.has(x)
    ? dupeMap[x] ??= d++
    : seen.add(x);
    }
    }

    for (const obj of myWrapper) {
    // collect elements into dupe/unique temp arrays
    const
    { foo } = obj,
    dTemp = [], uTemp = [];
    for (const e of foo) {
    (e in dupeMap)
    ? dTemp[dupeMap[e]] = e
    : uTemp.push(e);
    }

    // backfill empty indexes in dupe temp array
    for (const [i, d] of dTemp.entries()) {
    if (d === undefined && uTemp.length) {
    dTemp.splice(i, 1, uTemp.shift());
    }
    }

    // concat back into foo
    obj.foo = [...dTemp, ...uTemp];
    }

    myWrapper.forEach(({ foo }) => console.log(`{foo: [${foo.map(e => e ?? ' ').join(', ')}]}`));
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    关于Javascript:对齐并行数组索引避免重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67583456/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com