简体   繁体   中英

javascript array filter duplicates by object key

I have an array of objects in Javascript

I am trying to filter out duplicates by object value

  1. get duplicate

  2. 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'
}];

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; }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM