Say I have an array of [34, 35, 45, 48, 49]
and another array of [48, 55]
. How can I get a resulting array of [34, 35, 45, 48, 49, 55]
?
-
with ES6 goodies it will be just a oneliner with no dependencies. Sad that we need to wait a lot of time before it will be available in all modern browsers. Anyway, check [my answer](http://stackoverflow.com/a/27997088/1090562) – Salvador Dali Jan 17 '15 at 07:06
-
[This](http://codegolf.stackexchange.com/a/17129) implementation in Code Golf is IMO the most elegant and efficient solution out there. – Sayan Oct 19 '15 at 06:16
21 Answers
With the arrival of ES6 with sets and spread operator, you can write the following cryptic one liner:
var a = [34, 35, 45, 48, 49];
var b = [48, 55];
var union = [...new Set([...a, ...b])];
console.log(union);
Little explanation about this line: [...a, ...b]
concatenates two arrays, you can use a.concat(b)
as well. new Set()
create a set out of it and thus your union. And the last [...x]
converts it back to an array.

- 2,815
- 3
- 22
- 31

- 214,103
- 147
- 703
- 753
-
-
1@RPallas I have not done any testing (you can easily do them here https://jsperf.com/). But all the functions here are native, which suggests that it should be faster then anything non-native. – Salvador Dali Mar 18 '15 at 19:50
-
Performance test here: https://jsperf.com/union-speeds/1 It's a bit slower than the lodash solution, but unlikely to matter unless you're performing lots of big unions in real-time. And if that's the case, you should probably look into an even faster solution like Lazy.js – Tony Boyles May 30 '17 at 17:44
-
4Typescript was complaining and I replaced the spread operator with `Array.from(new Set([...a, ...b]))` and it worked. – Agu V Apr 03 '19 at 13:36
If you don't need to keep the order, and consider 45
and "45"
to be the same:
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]));

- 3,737
- 4
- 33
- 56

- 510,854
- 105
- 1,084
- 1,005
-
-
2This will fail for arrays of objects. union_arrays([{a:1}], [{b:2}]) will return [{b:2}]. – EricP Jul 04 '14 at 14:39
-
Why not skip declaring res and the whole "for( var k in obj)... push..." and just return Object.keys(obj)? You can also combine those two initial for-loops into one with "var both = x.concat(y)" to concatenate the two arrays into one. That way, you can union any number of arrays, too. – Jemenake May 27 '15 at 04:12
-
-
-
I had performance problem with this answer that made chrome crash. See http://stackoverflow.com/a/25120770/216057 for a performance approach of different solutions. – Rémy DAVID Oct 13 '15 at 13:19
If you use the library underscore you can write like this
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>

- 3,737
- 4
- 33
- 56

- 10,951
- 6
- 52
- 65
-
2I wouldn't normally reference a whole new library for one small piece of functionality, but the underscore library has a LOT of really useful functions to work with arrays. I also ended up using the _.intersection and _.without functions. – Ben Mills Feb 02 '15 at 18:01
-
6Lodash also has a [great implementation for union](https://lodash.com/docs/4.17.4#union) – BGilman May 15 '17 at 20:23
I'm probably wasting time on a dead thread here. I just had to implement this and went looking to see if I was wasting my time.
I really like KennyTM's answer. That's just how I would attack the problem. Merge the keys into a hash to naturally eliminate duplicates and then extract the keys. If you actually have jQuery you can leverage its goodies to make this a 2 line problem and then roll it into an extension. The each() in jQuery will take care of not iterating over items where hasOwnProperty() is 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;
}
});
Note that both of the original arrays are left intact. Then you call it like this:
var union = $.union(array1, array2);

- 1,661
- 1
- 18
- 24
-
I think this is the best answer there is because this function appears to work in `O(2n)` (faster due to the two non-nested for loops) as opposed to the rest which appear to work in a `O(n^2)` (slower) fashion. – Hengjie Mar 02 '13 at 00:31
-
Hengjie, Really O(2n)? I think, $.merge has O(n) or even O(n*n) not O(1). This can be optimized to O(3n) if fill hash separately without merges – vp_arth Sep 23 '13 at 05:47
-
1
-
3
If you wants to concatenate two arrays without any duplicate value,Just try this
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;} );

- 161
- 3
- 11
-
-
1
-
1nice! or a variation if you are already in a method chaining (you don't have a reference to c): ``` [1,2,3].concat([2,3,4]) .filter((value, pos, arr)=>arr.indexOf(value)===pos)}``` – cancerbero May 29 '18 at 05:25
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);

- 3,737
- 4
- 33
- 56

- 3,074
- 11
- 43
- 62
-
Maybe I'm just confused, but how would this work? You're passing arr3, but there is no arr3, and even if there was it doesn't look like it's actually a union on arr1 | arr2 like he requested? – Angelo R. Sep 02 '10 at 18:06
-
2
-
1
-
var arr2 = []; if (currTaskIDs != '') { if( $.inArray(currTaskIDs, arr2) == -1) { arr2.push(currTaskIDs); } arr2 = unique(arr2.concat(arr)); } } now, currTaskIDs is = 34,35,45,48,49 if i select say 50, it removes all of them and just displays 50 – CFNinja Sep 02 '10 at 18:11
-
by the way, if i just use this: var currTaskIDs = $("#taskIDList").val(); // begin: create the task list: if (currTaskIDs != '') { if( $.inArray(currTaskIDs, arr) == -1) { arr.push(currTaskIDs); } arr = unique(arr); } it works perfectly first time. if i add another value to my currTaskIDs, then it becomes something like : 34,35,45,48,49,50,34,35,45,48,49,50,38 – CFNinja Sep 02 '10 at 18:14
-
try this : if( $.inArray(currTaskIDs, arr) == -1) { arr.push(currTaskIDs); } var AnotherNewArr = unique(arr); Without seeing full code, i cant be sure what you're doing exactly, but it may be a clearing issue. – Bob Sep 02 '10 at 18:19
-
I've tried this function at http://www.squarefree.com/jsenv/ and added print(union); and it works fine, even after adding more data to the array – Bob Sep 02 '10 at 18:24
-
-
this is driving me nuts but still no luck. this is my current code minus the unique function above: var tid = $(this).attr('name').split('-')[1]; var j = $(this).attr('name').split('-')[2]; var currTaskIDs = $("#taskIDList").val(); // begin: create the task list: var arr2 = []; if (currTaskIDs != '') { if( $.inArray(currTaskIDs, arr) == -1) { arr.push(currTaskIDs); } arr2 = unique(arr); alert(arr2); } if( $.inArray(tid, arr) == -1) { arr.push(tid); } the very first time i pick a new selection it works. – CFNinja Sep 02 '10 at 18:34
-
but if i go back and add another selection then it becomes 4,35,45,48,49,36,34,35,45,48,49,36,37,34,35,45,48,49,36,34,35,45,48,49,36,37,51 – CFNinja Sep 02 '10 at 18:34
Adapted from: 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
I like Peter Ajtai's concat-then-unique solution, but the code's not very clear. Here's a nicer alternative:
function unique(x) {
return x.filter(function(elem, index) { return x.indexOf(elem) === index; });
};
function union(x, y) {
return unique(x.concat(y));
};
Since indexOf returns the index of the first occurence, we check this against the current element's index (the second parameter to the filter predicate).

- 2,611
- 1
- 29
- 23
Shorter version of kennytm's answer:
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]);
};

- 174
- 9
You can use a jQuery plugin: jQuery Array Utilities
For example the code below
$.union([1, 2, 2, 3], [2, 3, 4, 5, 5])
will return [1,2,3,4,5]

- 111
- 1
- 4
-
This union function also supports an arbitrary number of arrays, This package [jquery-array-utilities](https://libraries.io/bower/jquery-array-utilities) can also be installed using [bower](https://bower.io). I would like like to add a disclaimer that I originally made the plugin :) – Kristian Abrahamsen Nov 28 '16 at 21:28
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;
}
var unionArr = unionArray([34, 35, 45, 48, 49], [44, 55]);
console.log(unionArr);

- 3,737
- 4
- 33
- 56

- 2,799
- 1
- 17
- 25
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;
}
var unionArr = unionArrays([34, 35, 45, 48, 49], [44, 55]);
console.log(unionArr);
Somewhat similar in approach to alejandro's method, but a little shorter and should work with any number of arrays.

- 3,737
- 4
- 33
- 56

- 21
- 1
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 :)

- 934
- 1
- 16
- 25
I would first concatenate the arrays, then I would return only the unique value.
You have to create your own function to return unique values. Since it is a useful function, you might as well add it in as a functionality of the Array
.
In your case with arrays array1
and array2
it would look like this:
array1.concat(array2)
- concatenate the two arraysarray1.concat(array2).unique()
- return only the unique values. Hereunique()
is a method you added to the prototype forArray
.
The whole thing would look like this:
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
console.log(array1.concat(array2).unique());

- 3,737
- 4
- 33
- 56

- 56,972
- 13
- 121
- 140
-
I prefer to use `if(r.indexOf(this[i])!==-1) continue;` instead inner loop and `r.push(this[i])` instead `r[r.length]=this[i]` here – vp_arth Sep 23 '13 at 05:14
Just wrote before for the same reason (works with any amount of arrays):
/**
* 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; }

- 15,810
- 18
- 109
- 172
Simple way to deal with merging single array values.
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)

- 30,841
- 27
- 92
- 100

- 11
- 2
You can try these:
function union(a, b) {
return a.concat(b).reduce(function(prev, cur) {
if (prev.indexOf(cur) === -1) prev.push(cur);
return prev;
}, []);
}
or
function union(a, b) {
return a.concat(b.filter(function(el) {
return a.indexOf(el) === -1;
}));
}

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

- 2,982
- 1
- 26
- 29
-
-
Do explain how adding functionality equates to contamination. Opinions are welcome as long as they are backed by logical reasoning. – Adnan Y May 30 '18 at 00:22
-
Fair enough. I'm sorry whatever happened to you. Still it would be nice to keep the personal experiences personal. This is not a scratchpad. It's a QA site. – Adnan Y Jun 06 '18 at 18:28
-
If you want a custom equals function to match your elements, you can use this function in ES2015:
function unionEquals(left, right, equals){
return left.concat(right).reduce( (acc,element) => {
return acc.some(elt => equals(elt, element))? acc : acc.concat(element)
}, []);
}
It traverses the left+right array. Then for each element, will fill the accumulator if it does not find that element in the accumulator. At the end, there are no duplicate as specified by the equals
function.
Pretty, but probably not very efficient with thousands of objects.

- 6,910
- 3
- 50
- 74
I think it would be simplest to create a new array, adding the unique values only as determined by indexOf.
This seems to me to be the most straightforward solution, though I don't know if it is the most efficient. Collation is not preserved.
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;
}

- 1,226
- 1
- 14
- 13
[i for( i of new Set(array1.concat(array2)))]
Let me break this into parts for you
// 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)
)
)
]
In other words, it first concatenates both and then it removes the duplicates (a Set, by definition cannot have duplicates)
Do note, though, that the order of the elements is not guaranteed, in this case.

- 6,258
- 8
- 39
- 59