在JavaScript中获得两个数组的联合

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

如果你不需要保留这个命令,并且考虑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; } alert(union_arrays([34,35,45,48,49], [44,55])); // shows [49, 48, 45, 35, 34, 55, 44] 

随着ES6与集合和图示操作符的到来(在Firefox只工作时,检查兼容性表),您可以编写以下神秘的一行:

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

这将输出像[ 34, 35, 45, 48, 49, 55 ]

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

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

 _.union([34,35,45,48,49], [48,55]); // [34, 35, 45, 48, 49, 55] 

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

我可能在这里死去的线程上浪费时间。 我只是要实现这个,去看看我是否浪费了我的时间。

我真的很喜欢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); 
 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)); 

改编自: https : //stackoverflow.com/a/4026828/1830259

 Array.prototype.union = function(a) { var r = this.slice(0); a.forEach(function(i) { if (r.indexOf(i) < 0) r.push(i); }); return r; }; Array.prototype.diff = function(a) { return this.filter(function(i) {return a.indexOf(i) < 0;}); }; var s1 = [1, 2, 3, 4]; var s2 = [3, 4, 5, 6]; console.log("s1: " + s1); console.log("s2: " + s2); console.log("s1.union(s2): " + s1.union(s2)); console.log("s2.union(s1): " + s2.union(s1)); console.log("s1.diff(s2): " + s1.diff(s2)); console.log("s2.diff(s1): " + s2.diff(s1)); // Output: // s1: 1,2,3,4 // s2: 3,4,5,6 // s1.union(s2): 1,2,3,4,5,6 // s2.union(s1): 3,4,5,6,1,2 // s1.diff(s2): 1,2 // s2.diff(s1): 5,6 

我喜欢Peter Ajtai的concat-then-unique解决scheme,但代码不是很清楚。 这是一个更好的select:

 function unique(x) { return x.filter(function(elem, index) { return x.indexOf(elem) === index; }); }; function union(x, y) { return unique(x.concat(y)); }; 

由于indexOf返回第一个事件的索引,我们根据当前元素的索引(filter谓词的第二个参数)来检查这个索引。

你可以使用jQuery插件: jQuery Array Utilities

例如下面的代码

 $.union([1, 2, 2, 3], [2, 3, 4, 5, 5]) 

将返回[1,2,3,4,5]

我将首先连接数组,然后我将只返回唯一的值。

你必须创build你自己的函数来返回唯一的值。 由于它是一个有用的function,所以您可以将其添加为Array的function 。

你的情况与数组array1array2它看起来像这样:

  1. array1.concat(array2) – 连接两个数组
  2. array1.concat(array2).unique() – 只返回唯一值。 这里unique()是你添加到Array的原型的一个方法。

整个事情看起来像这样:

jsFiddle的例子

 Array.prototype.unique = function () { var r = new Array(); o:for(var i = 0, n = this.length; i < n; i++) { for(var x = 0, y = r.length; x < y; x++) { if(r[x]==this[i]) { continue o; } } r[r.length] = this[i]; } return r; } var array1 = [34,35,45,48,49]; var array2 = [34,35,45,48,49,55]; // concatenate the arrays then return only the unique values alert(array1.concat(array2).unique()); 
 function unite(arr1, arr2, arr3) { newArr=arr1.concat(arr2).concat(arr3); a=newArr.filter(function(value){ return !arr1.some(function(value2){ return value == value2; }); }); console.log(arr1.concat(a)); }//This is for Sorted union following the order :) 
 function unionArray(arrayA, arrayB) { var obj = {}, i = arrayA.length, j = arrayB.length, newArray = []; while (i--) { if (!(arrayA[i] in obj)) { obj[arrayA[i]] = true; newArray.push(arrayA[i]); } } while (j--) { if (!(arrayB[j] in obj)) { obj[arrayB[j]] = true; newArray.push(arrayB[j]); } } return newArray; } unionArray([34, 35, 45, 48, 49], [44, 55]); 

加快http://jsperf.com/union-array-faster

 function unionArrays() { var args = arguments, l = args.length, obj = {}, res = [], i, j, k; while (l--) { k = args[l]; i = k.length; while (i--) { j = k[i]; if (!obj[j]) { obj[j] = 1; res.push(j); } } } return res; } 

与alejandro的方法有一些相似之处,但稍微短一点,应该可以处理任意数量的数组。

之前刚刚写过,出于同样的原因(适用于任何数量的数组):

 /** * Returns with the union of the given arrays. * * @param Any amount of arrays to be united. * @returns {array} The union array. */ function uniteArrays() { var union = []; for (var argumentIndex = 0; argumentIndex < arguments.length; argumentIndex++) { eachArgument = arguments[argumentIndex]; if (typeof eachArgument !== 'array') { eachArray = eachArgument; for (var index = 0; index < eachArray.length; index++) { eachValue = eachArray[index]; if (arrayHasValue(union, eachValue) == false) union.push(eachValue); } } } return union; } function arrayHasValue(array, value) { return array.indexOf(value) != -1; } 

处理合并单个数组值的简单方法。

 var values[0] = {"id":1235,"name":"value 1"} values[1] = {"id":4323,"name":"value 2"} var object=null; var first=values[0]; for (var i in values) if(i>0) object= $.merge(values[i],first) 

你可以试试这些:

 function union(a, b) { return a.concat(b).reduce(function(prev, cur) { if (prev.indexOf(cur) === -1) prev.push(cur); return prev; }, []); } 

要么

 function union(a, b) { return a.concat(b.filter(function(el) { return a.indexOf(el) === -1; })); } 

ES2015版本

 Array.prototype.diff = function(a) {return this.filter(i => a.indexOf(i) < 0)}; Array.prototype.union = function(a) {return [...this.diff(a), ...a]} 

kennytm的答案较短的版本:

 function unionArrays(a, b) { const cache = {}; a.forEach(item => cache[item] = item); b.forEach(item => cache[item] = item); return Object.keys(cache).map(key => cache[key]); }; 

如果你想连接两个没有任何重复值的数组,请试试这个

 var a=[34, 35, 45, 48, 49]; var b=[48, 55]; var c=a.concat(b).sort(); var res=c.filter((value,pos) => {return c.indexOf(value) == pos;} ); 

我认为创build一个新的数组是最简单的,只添加indexOf确定的唯一值。

这在我看来是最直接的解决scheme,但我不知道它是否是最有效的。 整理不保留。

 var a = [34, 35, 45, 48, 49], b = [48, 55]; var c = union(a, b); function union(a, b) { // will work for n >= 2 inputs var newArray = []; //cycle through input arrays for (var i = 0, l = arguments.length; i < l; i++) { //cycle through each input arrays elements var array = arguments[i]; for (var ii = 0, ll = array.length; ii < ll; ii++) { var val = array[ii]; //only add elements to the new array if they are unique if (newArray.indexOf(val) < 0) newArray.push(val); } } return newArray; } 
 [i for( i of new Set(array1.concat(array2)))] 

让我把它分成几部分给你

 // This is a list by comprehension // Store each result in an element of the array [i // will be placed in the variable "i", for each element of... for( i of // ... the Set which is made of... new Set( // ...the concatenation of both arrays array1.concat(array2) ) ) ] 

换句话说,它首先连接两个,然后删除重复项(一个Set,根据定义不能有重复)

但请注意,在这种情况下,元素的顺序是不能保证的。

如果你想要一个自定义等号函数来匹配你的元素,你可以在ES2015中使用这个函数:

 function unionEquals(left, right, equals){ return left.concat(right).reduce( (acc,element) => { return acc.some(elt => equals(elt, element))? acc : acc.concat(element) }, []); } 

它遍历左+右数组。 那么对于每个元素,如果没有在累加器中find该元素,将填充累加器。 最后,不存在equals函数指定的重复项。

漂亮,但可能不是很有效的数以千计的对象。