Reputation: 23
I have an array of objects in Javascript
I am trying to filter out duplicates by object value
get duplicate
get unique
example arrays:
let array = [
{
id: '001',
name: 'aaa',
type_id: 'a111'
},{
id: '002',
name: 'bbb',
type_id: 'a111'
},{
id: '003',
name: 'ccc',
type_id: 'a222'
},{
id: '004',
name: 'ddd',
type_id: 'a333'
}];
This is what i want my array to turn out like:
function 1(array, 'type_id')
[{
id: '001',
name: 'aaa',
type_id: 'a111'
},{
id: '002',
name: 'bbb',
type_id: 'a111'
}];
function 2(array, 'type_id')
[{
id: '003',
name: 'ccc',
type_id: 'a222'
},{
id: '004',
name: 'ddd',
type_id: 'a333'
}];
Upvotes: 2
Views: 1518
Reputation: 386604
You could take a Map
for same type_id
and collect the objects and then push the mapped items to either unique or dupes, based of the length of the array.
The line
map.forEach(a => [unique, dupes][a.length - 1 && 1].push(...a));
takes the map and iterates all elements of it and uses a target array of unique
and dupes
,
[unique, dupes] // targets
takes the length of the maped array, for separating the target array
[a.length - 1 && 1] // select target
Cosider this list for getting an index, 0
for unique items and 1
for duplicates. A lenght of zero does not exist, because if a map entry is made, the length is one.
length length - 1 length - 1 && 1 comment ------ ---------- --------------- -------- 1 0 0 take `length - 1`, because of falsy 1st operand 2 1 1 take 2nd operand 3 2 1 take 2nd operand 4 3 1 take 2nd operand for all other greater length
Then with spread syntax ...
, all items of the array a
are used as parameters for Array#push
.
.push(...a) // push all itmes of array
var array = [{ id: '001', name: 'aaa', type_id: 'a111' }, { id: '002', name: 'bbb', type_id: 'a111' }, { id: '003', name: 'ccc', type_id: 'a222' }, { id: '004', name: 'ddd', type_id: 'a333' }],
key = 'type_id',
map = new Map,
unique = [],
dupes = [];
array.forEach(o => map.set(o[key], (map.get(o[key]) || []).concat(o)));
map.forEach(a => [unique, dupes][a.length - 1 && 1].push(...a));
console.log(unique);
console.log(dupes);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 114
I've written some code to do those things you wanted to achieve:
let array = [{
id: '001',
name: 'aaa',
type_id: 'a111'
}, {
id: '002',
name: 'bbb',
type_id: 'a111'
}, {
id: '003',
name: 'ccc',
type_id: 'a222'
}, {
id: '004',
name: 'ddd',
type_id: 'a333'
}];
var duplicates = [];
var uniques = [];
var valueCounts = {};
function getDuplicatesAndUniques(array, value) {
for (var i = 0; i < array.length; i++) {
if (!valueCounts[array[i][value]])
valueCounts[array[i][value]] = 1;
else
valueCounts[array[i][value]]++;
}
for (var i = 0; i < array.length; i++) {
if (valueCounts[array[i][value]] == 1) {
uniques.push(array[i]);
} else {
duplicates.push(array[i]);
}
}
}
getDuplicatesAndUniques(array, "type_id");
console.log(duplicates);
console.log(uniques);
https://jsfiddle.net/hbpx08xh/1/
Hope this helps! :)
Best Regards
Upvotes: 1