【问题标题】:Generating unique combinations from a nested array (JS)从嵌套数组 (JS) 生成唯一组合
【发布时间】:2017-06-22 19:04:17
【问题描述】:

我正在尝试从 Javascript 中的数组数组生成唯一组合。

Input: [ [1,1,3], [3,1,1], [4,4,4] ]
Output: [ [1,1,3], [4,4,4] ]

在此示例中,[3,1,1][1,1,3] 的副本。将数字添加到 Set 似乎并不能解决重复数组的问题,并且散列排序的字符串化数组似乎是一种 hack。

编辑:寻找不涉及字符串化数组的解决方案(如果存在)。

有没有更好的方法来解决这个问题?

【问题讨论】:

  • 您是在寻找独特的数组还是这些数组的组合 - 例如电源组?
  • 只是组合,所以我们会以不同的顺序删除具有相同数字的数组。
  • 看来您将不得不编写一个小程序来做到这一点。首先用英语写下需要做的事情,包括您计划如何将数组与不同顺序的元素进行比较。然后,将其编写为 JavaScript 程序。
  • 数组是否总是只有数字或其他原始值的数组?
  • 是的,只是整数。

标签: javascript arrays algorithm combinations


【解决方案1】:

您可以使用带有排序字符串数组的集合并进行相应的过滤。

var array = [[1, 1, 3], [3, 1, 1], [4, 4, 4]],
    unique = array.filter(
        (s => a => (p => !s.has(p) && s.add(p))(a.slice().sort((a, b) => a - b).join()))(new Set)
    );

console.log(unique);

一种稍微不同的方法,没有字符串化数组,但使用嵌套哈希表,它使用长度作为第一个键。

var array = [[1, 1, 3], [3, 1, 1], [4, 4, 4]],
    unique = array.filter(function (hash) {
        return function (a) {
            var found = true;
				
            a   .slice()
                .sort(function (a, b) { return a - b; })
                .reduce(function (r, k) {
                    found = found && r[k];
                    return r[k] = r[k] || {};
                }, hash[a.length] = hash[a.length] || {});
            return !found;
        };
    }(Object.create(null)));

console.log(unique);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    将数组映射到原始哈希值可以有效地识别重复项 - 在您的情况下是排列。

    一个简单的散列函数是通过对数组进行排序并连接或字符串化来给出的,您希望避免这种情况。

    对于范围有限的整数数组,您可以将每个整数 n 映射到第 n 个素数。这些主要因素的乘积就是你的哈希值。由于可以在线性时间内计算乘积,因此这比以存储可能很大的素数数组为代价的排序要快:

    const primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61];
    
    function hash(numbers) {
      return numbers.reduce((prod, n) => prod * primes[n], 1);
    }
    
    function unique(arrays) {
      let set = new Set();
      return arrays.filter(numbers => {
        let h = hash(numbers);
        return !set.has(h) && set.add(h);
      });
    }
    
    console.log(unique([[1,1,3], [3,1,1], [4,4,4]]));

    【讨论】:

    • 您使用 Map 和 Nina's Set 的运行时间复杂度有何不同?
    • 嗨@Arrow,运行时复杂度没有区别,但再想想我宁愿使用Set,因为Map.values() 迭代器在这里没有多大意义。跨度>
    【解决方案3】:
    var output=Object.keys(input.reduce((obj,el)=>(obj[el.sort().join()]=true,obj),{})).map(arr=>arr.split().map(e=>+e));
    

    您可以对数组进行排序,使它们相等,并使用哈希表使整个事物独一无二。

    【讨论】:

    • 很好,您还需要再次映射以转换回 int。但这是我试图避免的“散列排序的、字符串化的数组”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多