Reputation: 127
I want concat following two arrays by removing duplicates without assigning to third variable:
var arr1=[{id:1,name:'AB'},{id:2,name:'CD'}];
var arr2=[{id:3,name:'EF'},{id:2,name:'CD'}];
I want arr1 like:
[{id:1,name:'AB'},{id:2,name:'CD'},{id:3,name:'EF'}]
arr1.concat(arr2);
Upvotes: 6
Views: 23401
Reputation: 1
Here I use splice to remove the first element in arr2 and concat it to arr1.
let arr1=[{id:1,name:'AB'},{id:2,name:'CD'}];
let arr2=[{id:3,name:'EF'},{id:2,name:'CD'}];
console.log(arr1.concat(arr2.splice(0,1)));
Upvotes: 0
Reputation: 1862
Both lodash function unionBy
and unionWith
can solve your problem.
If your objects has unique key, unionBy
is the most elegant way to handle it.
var arr1 = [{id:1,name:'AB'},{id:2,name:'CD'}];
var arr2 = [{id:3,name:'EF'},{id:2,name:'CD'}];
var mergedWithoutDups = _.unionBy(arr1, arr2. 'id')
If your object has no unique key, use unionWith
and isEqual
instead. This will take deep comparison on all objects to remove duplicate.
var arr1 = [{id:1,name:'AB'},{id:2,name:'CD'}];
var arr2 = [{id:3,name:'EF'},{id:2,name:'CD'}];
var mergedWithoutDups = _.unionWith(arr1, arr2. _.isEqual)
Upvotes: 0
Reputation: 221
If you like clean ES6 try this:
Happy code :)
function arrayWithNoDuplicates(array, field) {
const arrayWithoutNoDuplicates = array.filter((value, index, self) =>
index === self.findIndex((t) => (
t[field] === value[field]
))
)
return arrayWithoutNoDuplicates
}
const arr1 = [{id:1,name:'AB'}, {id:2,name:'CD'}]
const arr2 = [{id:3,name:'EF'}, {id:2,name:'CD'}]
// The first param is the two merged arrays and the second the field you
// to filter by
console.log(arrayWithNoDuplicates([...arr1, ...arr2], 'id'))
Upvotes: 1
Reputation: 600
Here is the one liner that compares by id
.
let result = arr1.concat( arr2.filter( i2 => !arr1.find( i1 => i1.id == i2.id ) ) );
I have modified elements to show what happens for different objects with the same id
. Swap arr1
with arr2
for which array you want to keep your preferred components. There seems to be no simple way to compare objects in JavaScript, you may use JSON.stringify
but that depends on elements order. You can try it out at https://playcode.io/new/ :
var arr1=[{id:1,name:'AB'},{id:2,name:'CD'}];
var arr2=[{id:3,name:'EF'},{id:2,name:'GH'}];
let result;
result = arr1.concat( arr2.filter( i2 => !arr1.find( i1 => i1.id == i2.id ) ) );
console.log('RESULT: ' + JSON.stringify(result));
result = arr1.concat(
arr2.filter(
i2 => !arr1.find(
i1 => {
console.log('I1: ' + JSON.stringify(i1) + ' I2: ' + JSON.stringify(i2));
return i1.id == i2.id;}
)
)
);
console.log('RESULT: ' + JSON.stringify(result));
result = arr2.concat(
arr1.filter(
i1 => !arr2.find(
i2 => {
console.log('I1: ' + JSON.stringify(i1) + ' I2: ' + JSON.stringify(i2));
return i1.id == i2.id;}
)
)
);
console.log('RESULT: ' + JSON.stringify(result));
Upvotes: 0
Reputation: 26
var arr1 = [{ id: 1, name: 'AB' }, { id: 2, name: 'CD' }];
var arr2 = [{ id: 3, name: 'EF' }, { id: 3, name: 'XX' }];
arr1.forEach(element => {
arr2.forEach((el, idx) => {
if (element.id === el.id || element.name === el.name) {
delete arr2[idx]
}
});
});
let data = arr1.concat(arr2)
// or arr1 = arr1.concat(arr2)
// then your arr1 contains your unique array
data variable contains your unique array
Upvotes: 0
Reputation: 1960
using the spread
operator you can flatten any amount of arrays passed to the combineAndDeDup
method, i have also split out some logic methods for (hopefully) more readable code. i hope this helps.
const arr1 = [{id:1,name:'AB'}, {id:2,name:'CD'}]
const arr2 = [{id:3,name:'EF'}, {id:2,name:'CD'}]
const flatten = a => [].concat.apply([], a)
const noDuplicateProps = (a, b) => Object.keys(a).some(k => a[k] === b[k])
const combineAndDeDup = (...arrs) => {
return flatten(arrs).reduce((acc, item) => {
const uniqueItem = acc.findIndex(i => noDuplicateProps(i, item)) === -1
if (uniqueItem) return acc.concat([ item ])
return acc
}, [])
}
const deDuped = combineAndDeDup(arr1, arr2)
const megaDeDuped = combineAndDeDup(arr1, arr2, arr1, arr1, arr2, arr1)
console.log(deDuped)
console.log(megaDeDuped)
Upvotes: 1
Reputation: 4648
First merge two arrays then put array into a map with their ids. Then create array from map values.
var arr1=[{id:1,name:'AB'},{id:2,name:'CD'}];
var arr2=[{id:3,name:'EF'},{id:2,name:'CD'}];
arr1 = arr1.concat(arr2) // merge two arrays
let foo = new Map();
for(const tag of arr1) {
foo.set(tag.id, tag);
}
let final = [...foo.values()]
console.log(final)
Upvotes: 7
Reputation: 5254
By using lodash _.uniqWith(array, [comparator])
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.uniqWith(objects, _.isEqual);
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
Upvotes: 0
Reputation: 12960
Can use Array reduce and findIndex to achieve what you want.
var arr1=[{id:1,name:'AB'},{id:2,name:'CD'}];
var arr2=[{id:3,name:'EF'},{id:2,name:'CD'}];
// loop over arr2, add the elements of array2 if it doesn't exist in array1
var newArr = arr2.reduce((acc, eachArr2Elem) => {
if (arr1.findIndex((eachArr1Elem) => eachArr1Elem.id === eachArr2Elem.id && eachArr1Elem.name === eachArr2Elem.name) === -1) {
acc.push(eachArr2Elem)
}
return acc
}, [...arr1]); // initialize the new Array with the contents of array1
console.log(newArr)
Upvotes: 6