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]
?
This question is related to
javascript
arrays
[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.
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 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;
}
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 :)
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);
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. Here unique()
is a method you added to the prototype for Array
.The whole thing would look like this:
Array.prototype.unique = function () {_x000D_
var r = new Array();_x000D_
o: for(var i = 0, n = this.length; i < n; i++)_x000D_
{_x000D_
for(var x = 0, y = r.length; x < y; x++)_x000D_
{_x000D_
if(r[x]==this[i])_x000D_
{_x000D_
continue o;_x000D_
}_x000D_
}_x000D_
r[r.length] = this[i];_x000D_
}_x000D_
return r;_x000D_
}_x000D_
var array1 = [34,35,45,48,49];_x000D_
var array2 = [34,35,45,48,49,55];_x000D_
_x000D_
// concatenate the arrays then return only the unique values_x000D_
console.log(array1.concat(array2).unique());
_x000D_
function unique(arrayName)_x000D_
{_x000D_
var newArray=new Array();_x000D_
label: for(var i=0; i<arrayName.length;i++ )_x000D_
{ _x000D_
for(var j=0; j<newArray.length;j++ )_x000D_
{_x000D_
if(newArray[j]==arrayName[i]) _x000D_
continue label;_x000D_
}_x000D_
newArray[newArray.length] = arrayName[i];_x000D_
}_x000D_
return newArray;_x000D_
}_x000D_
_x000D_
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);_x000D_
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);_x000D_
var union = unique(arr1.concat(arr2));_x000D_
console.log(union);
_x000D_
function unionArray(arrayA, arrayB) {_x000D_
var obj = {},_x000D_
i = arrayA.length,_x000D_
j = arrayB.length,_x000D_
newArray = [];_x000D_
while (i--) {_x000D_
if (!(arrayA[i] in obj)) {_x000D_
obj[arrayA[i]] = true;_x000D_
newArray.push(arrayA[i]);_x000D_
}_x000D_
}_x000D_
while (j--) {_x000D_
if (!(arrayB[j] in obj)) {_x000D_
obj[arrayB[j]] = true;_x000D_
newArray.push(arrayB[j]);_x000D_
}_x000D_
}_x000D_
return newArray;_x000D_
}_x000D_
var unionArr = unionArray([34, 35, 45, 48, 49], [44, 55]);_x000D_
console.log(unionArr);
_x000D_
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]}
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;} );
If you use the library underscore you can write like this
var unionArr = _.union([34,35,45,48,49], [48,55]);_x000D_
console.log(unionArr);
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
_x000D_
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).
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.
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)
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;
}));
}
With the arrival of ES6 with sets and splat operator (at the time of being works only in Firefox, check compatibility table), you can write the following cryptic one liner:
var a = [34, 35, 45, 48, 49];_x000D_
var b = [48, 55];_x000D_
var union = [...new Set([...a, ...b])];_x000D_
console.log(union);
_x000D_
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.
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]
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]);
};
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; }
function unionArrays() {_x000D_
var args = arguments,_x000D_
l = args.length,_x000D_
obj = {},_x000D_
res = [],_x000D_
i, j, k;_x000D_
_x000D_
while (l--) {_x000D_
k = args[l];_x000D_
i = k.length;_x000D_
_x000D_
while (i--) {_x000D_
j = k[i];_x000D_
if (!obj[j]) {_x000D_
obj[j] = 1;_x000D_
res.push(j);_x000D_
}_x000D_
} _x000D_
}_x000D_
_x000D_
return res;_x000D_
}_x000D_
var unionArr = unionArrays([34, 35, 45, 48, 49], [44, 55]);_x000D_
console.log(unionArr);
_x000D_
Somewhat similar in approach to alejandro's method, but a little shorter and should work with any number of arrays.
Source: Stackoverflow.com