How to remove all duplicates from an array of objects? How to remove all duplicates from an array of objects? arrays arrays

How to remove all duplicates from an array of objects?


How about with some es6 magic?

things.thing = things.thing.filter((thing, index, self) =>  index === self.findIndex((t) => (    t.place === thing.place && t.name === thing.name  )))

Reference URL

A more generic solution would be:

const uniqueArray = things.thing.filter((thing, index) => {  const _thing = JSON.stringify(thing);  return index === things.thing.findIndex(obj => {    return JSON.stringify(obj) === _thing;  });});

Using the above property strategy instead of JSON.stringify:

const isPropValuesEqual = (subject, target, propNames) =>  propNames.every(propName => subject[propName] === target[propName]);const getUniqueItemsByProperties = (items, propNames) =>   items.filter((item, index, array) =>    index === array.findIndex(foundItem => isPropValuesEqual(foundItem, item, propNames))  );

You can add a wrapper if you want the propNames property to be either an array or a value:

const getUniqueItemsByProperties = (items, propNames) => {  const propNamesArray = Array.from(propNames);  return items.filter((item, index, array) =>    index === array.findIndex(foundItem => isPropValuesEqual(foundItem, item, propNamesArray))  );};

allowing both getUniqueItemsByProperties('a') and getUniqueItemsByProperties(['a']);

Stackblitz Example

Explanation

  • Start by understanding the two methods used:
  • Next take your idea of what makes your two objects equal and keep that in mind.
  • We can detect something as a duplicate, if it satisfies the criterion that we have just thought of, but it's position is not at the first instance of an object with the criterion.
  • Therefore we can use the above criterion to determine if something is a duplicate.


Shortest one liners for ES6+

Find unique id's in an array.

arr.filter((v,i,a)=>a.findIndex(t=>(t.id === v.id))===i)

Unique by multiple properties ( place and name )

arr.filter((v,i,a)=>a.findIndex(t=>(t.place === v.place && t.name===v.name))===i)

Unique by all properties (This will be slow for large arrays)

arr.filter((v,i,a)=>a.findIndex(t=>(JSON.stringify(t) === JSON.stringify(v)))===i)

Keep the last occurrence.

arr.slice().reverse().filter((v,i,a)=>a.findIndex(t=>(t.id === v.id))===i).reverse()


A primitive method would be:

var obj = {};for ( var i=0, len=things.thing.length; i < len; i++ )    obj[things.thing[i]['place']] = things.thing[i];things.thing = new Array();for ( var key in obj )    things.thing.push(obj[key]);