在 JavaScript 中获取两个数组的并集

IT技术 javascript arrays
2021-01-18 01:55:57

假设我有一个数组[34, 35, 45, 48, 49]和另一个数组[48, 55]. 我怎样才能得到一个结果数组[34, 35, 45, 48, 49, 55]

6个回答

随着带有集合和 splat 运算符的 ES6 的到来(当时仅适用于 Firefox,请查看兼容性表),您可以编写以下神秘的一行代码:

var a = [34, 35, 45, 48, 49];
var b = [48, 55];
var union = [...new Set([...a, ...b])];
console.log(union);

关于这一行的小解释:[...a, ...b]连接两个数组,你也可以使用a.concat(b)new Set()从中创建一个集合,从而创建您的工会。最后[...x]将其转换回数组。

性能测试在这里:jsperf.com/union-speeds/1它比 lodash 解决方案慢一点,但不太可能重要,除非您实时执行大量大型联合。如果是这种情况,你可能应该研究一个更快的解决方案,比如 Lazy.js
2021-03-27 01:55:57
typescript抱怨,我用Array.from(new Set([...a, ...b]))替换了扩展运算符,它起作用了。
2021-03-29 01:55:57
性能怎么样
2021-04-11 01:55:57
@RPallas 我没有做过任何测试(你可以在jsperf.com 上轻松完成)。但是这里的所有功能都是原生的,这表明它应该比任何非原生的都快。
2021-04-11 01:55:57

如果你不需要保持顺序,并且考虑45"45"是一样的:

function union_arrays (x, y) {
  var obj = {};
  for (var i = x.length-1; i >= 0; -- i)
     obj[x[i]] = x[i];
  for (var i = y.length-1; i >= 0; -- i)
     obj[y[i]] = y[i];
  var res = []
  for (var k in obj) {
    if (obj.hasOwnProperty(k))  // <-- optional
      res.push(obj[k]);
  }
  return res;
}

console.log(union_arrays([34,35,45,48,49], [44,55]));

@JemenakeObject.keys()在 2010 年不存在。
2021-03-16 01:55:57
不在乎顺序。这工作得很好。谢谢
2021-03-25 01:55:57
对于对象数组,这将失败。union_arrays([{a:1}], [{b:2}]) 将返回 [{b:2}]。
2021-03-28 01:55:57
也许i >= 0可以代替i
2021-04-04 01:55:57
为什么不跳过声明 res 和整个“for(var k in obj)... push...”而只返回 Object.keys(obj)?您还可以使用“var both = x.concat(y)”将这两个初始 for 循环合并为一个,以将两个数组合并为一个。这样,您也可以联合任意数量的数组。
2021-04-08 01:55:57

如果你使用库下划线,你可以这样写

var unionArr = _.union([34,35,45,48,49], [48,55]);
console.log(unionArr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>

参考http : //underscorejs.org/#union

我通常不会为一小部分功能引用一个全新的库,但下划线库有很多非常有用的函数来处理数组。我也最终使用了 _.intersection 和 _.without 函数。
2021-03-19 01:55:57
Lodash 也有一个很好的 union 实现
2021-03-25 01:55:57

我可能在这里浪费时间在一个死线程上。我只需要实现这一点,然后去看看我是否在浪费时间。

我真的很喜欢 KennyTM 的回答。这就是我将如何解决问题。将键合并成一个散列以自然地消除重复项,然后提取键。如果你真的有 jQuery,你可以利用它的优点把它变成一个 2 行问题,然后把它变成一个扩展。jQuery 中的 each() 将负责不迭代 hasOwnProperty() 为 false 的项目。

jQuery.fn.extend({
    union: function(array1, array2) {
        var hash = {}, union = [];
        $.each($.merge($.merge([], array1), array2), function (index, value) { hash[value] = value; });
        $.each(hash, function (key, value) { union.push(key); } );
        return union;
    }
});

请注意,两个原始数组都保持不变。然后你这样称呼它:

var union = $.union(array1, array2);
恒杰,真的O(2n)?我认为,$.merge 有 O(n) 甚至 O(n*n) 而不是 O(1)。如果单独填充散列而不合并,这可以优化为 O(3n)
2021-03-24 01:55:57
我认为这是最好的答案,因为这个函数似乎工作O(2n)(由于两个非嵌套 for 循环而更快),而不是其余的似乎以O(n^2)(较慢的)方式工作。
2021-03-25 01:55:57
@Hengjie:Kenny 的答案是 O(3n)
2021-04-07 01:55:57
O(n) == O(2n) == O(3n)
2021-04-10 01:55:57

function unique(arrayName)
{
  var newArray=new Array();
  label: for(var i=0; i<arrayName.length;i++ )
  {  
    for(var j=0; j<newArray.length;j++ )
    {
      if(newArray[j]==arrayName[i]) 
        continue label;
    }
    newArray[newArray.length] = arrayName[i];
  }
  return newArray;
}

var arr1 = new Array(0,2,4,4,4,4,4,5,5,6,6,6,7,7,8,9,5,1,2,3,0);
var arr2= new Array(3,5,8,1,2,32,1,2,1,2,4,7,8,9,1,2,1,2,3,4,5);
var union = unique(arr1.concat(arr2));
console.log(union);

我很困惑这怎么行不通?
2021-03-16 01:55:57
也许我只是感到困惑,但这将如何运作?您正在传递 arr3,但没有 arr3,即使有,它看起来也不像是实际上是 arr1 上的联合 | arr2 像他要求的那样?
2021-03-24 01:55:57
var arr2 = []; if (currTaskIDs != '') { if( $.inArray(currTaskIDs, arr2) == -1) { arr2.push(currTaskIDs); } arr2 = unique(arr2.concat(arr)); 现在,currTaskIDs 是 = 34,35,45,48,49 如果我选择说 50,它会删除所有这些并只显示 50
2021-04-05 01:55:57
顺便说一句,如果我只是使用这个: var currTaskIDs = $("#taskIDList").val(); // 开始:创建任务列表: if (currTaskIDs != '') { if( $.inArray(currTaskIDs, arr) == -1) { arr.push(currTaskIDs); } arr = 唯一的(arr); 它第一次完美运行。如果我向我的 currTaskIDs 添加另一个值,那么它会变成:34,35,45,48,49,50,34,35,45,48,49,50,38
2021-04-07 01:55:57
@Angelo R.:你说得对:“没有 arr3。”
2021-04-13 01:55:57