【问题标题】:Merge and sort multiple arrays using their ordering logic使用它们的排序逻辑合并和排序多个数组
【发布时间】:2021-05-16 08:50:26
【问题描述】:

我有一个数组数组,它​​们是根据给定位置排序的。

例如:

const test_arrays = [
['H', 'A'],
['X', 'K', 'Z', 'H', 'B', 'A'],
['M', 'H', 'B'],
['X', 'M', 'D','H', 'T', 'B'],
['X', 'D', 'K', 'Z']
]

我的目标是合并它们并删除重复但保持顺序。例如,我期望得到['X', 'M', 'D', 'K', 'Z', 'H', 'T', 'B', 'A']的结果

到目前为止我所做的尝试: Merge arrays and keep ordering

与上面的帖子类似,可能会有冲突,但这里有以下规则:

  • 如果由于信息不足而无法确定项目的最终位置,则第一个应该在第二个之前有一个索引。 例如
const arrays = [
['X', 'H'],
['X', 'C']
]

结果应该是['X','H','C']

  • 每个项目都应出现在最终输出中
  • 如果一个项目出现在多个数组中的不同位置,则第一个出现是正确的(跳过其他)。

Merge arrays and keep ordering解决的问题是:

  1. 当第一个数组不以“X”开头时,整个结果数组会放错位置。
  2. 当第一项时该项错位:当数组不以“X”开头时,新项“M”将位于结果字符串的末尾,而不是位于“X”和“D”之间。

这是我使用上面链接中的这些代码的结果数组:

var test_array_sorted=[];
test_arrays.forEach(array => {
                    array.forEach((item, idx) => {
                        // check if the item has already been added, if not, try to add
                        if(!~test_array_sorted.indexOf(item)) {
                            // if item is not first item, find position of his left sibling in result array
                            if(idx) {
                                const result_idx = test_array_sorted.indexOf(array[idx - 1]);
                                // add item after left sibling position
                                test_array_sorted.splice(result_idx + 1, 0, item);
                                return;
                            }

                        test_array_sorted.push(item);
                        }
                    });
                });

我当前的结果 = ['H','T','B','A','X','K','Z','M','D']

最值得注意的是,“H”是项目中的第一个,尽管它应该在 'X','M','D','K','Z' 之后。 'D' 现在位于最后,即使它应该在 'K','Z','H','B','A' 之前。

欢迎任何帮助,并在此先感谢您!

【问题讨论】:

  • 如果可能,您是否必须进行管理?即如果第一个数组是 ['H', 'A'] 而第二个可能是 ['X', 'D', 'K', 'Z'] ?还是总有可能?
  • 嗨,莱夫,谢谢!在这种特殊情况下,结果数组应该是 ['H','A','X','D','K','Z'] 因为没有逻辑来确定序列。因此,结果数组将只是类似于 .concat 的合并解决方案。

标签: javascript arrays sorting merge


【解决方案1】:

使用.sort()对数组进行排序

test_array_sorted.sort()

【讨论】:

    【解决方案2】:

    您可以获取所有数组中索引为零的唯一值的数组,并通过查看其他数组上的索引来过滤它,如果它们的索引大于一(目前以负方式实现),则将其删除。然后过滤数组,去掉空数组。

    const
        topSort = (arrays) => {
            const result = [];
            while (arrays.length) {
                const
                    temp = [...new Set(arrays.map(([v]) => v))]
                        .filter(v => arrays.every(a => a.indexOf(v) < 1));
    
                if (!temp.length) throw new Error('Circular reference!');
                temp.forEach(v => {
                    result.push(v);
                    arrays = arrays.filter(a => {
                        if (a[0] === v) a.shift();
                        return a.length;
                    });
                });
            }
            return result;
        },
        arrays = [['H', 'A'], ['X', 'K', 'Z', 'H', 'B', 'A'], ['M', 'H', 'B'], ['X', 'M', 'D', 'H', 'T', 'B'], ['X', 'D', 'K', 'Z']],
        circularReference = [['x', 'c'], ['c', 'x']];
    
    console.log(...topSort(arrays));            // X M D K Z H T B A
    console.log(...topSort(circularReference)); // Exception: Circular reference!

    【讨论】:

    • 嗨,Nina,如果出现 test_arrays =[['x','c'],['c','x']] 这样的逻辑错误,弹出警报并跳出 while 循环的最佳方法是什么?
    • 您可以将数组与项目一起存储,如果为空,您会得到一个循环引用。请参阅编辑。
    猜你喜欢
    • 2022-06-13
    • 2015-12-18
    • 1970-01-01
    • 2020-08-09
    • 2023-03-18
    • 2016-01-01
    • 2022-11-13
    • 2021-08-04
    • 2014-05-17
    相关资源
    最近更新 更多