Remove duplicates from array of objects conditionally

Tags: , , ,



I’ve got an array of objects which have a property in common ‘label’. But some of them have properties that others don’t :

const array = [
    {
        label: 'thing',
        type: 'reg',
    },
    {
        label: 'thing',
        type: 'ville',
        id: 1,
    },
    {
        label: 'another_thing',
        type: 'ville',
        id: 2,
    },
    {
        label: 'something',
        type: 'dpt',
    }
];

And I want duplicates (those objects with the same ‘label’ value) in this array to be removed and to keep only those which have the ‘id’ property. I tried to do it with _.uniqBy but it takes the first occurrence of the duplicated object and doesn’t take the id property in consideration.

So my final array should look like because the duplicate with the same ‘label’ value but which has no id property has been removed :

const array = [
    {
        label: 'thing',
        type: 'ville',
        id: 1,
    },
    {
        label: 'another_thing',
        type: 'ville',
        id: 2,
    },
    {
        label: 'something',
        type: 'dpt',
    }
];

Answer

Reduce the array to a Map. If the item has an id or the label doesn’t exist in the Map, add it to the Map. Convert the Map’s .values() iterator to an array using Array.from():

const array = [{"label":"thing","type":"reg"},{"label":"thing","type":"ville","id":1},{"label":"something","type":"dpt"}];

const result = Array.from( // convert the Map's iterator to an array
  array.reduce((r, o) =>
    'id' in o || !r.has(o.label) ? // if the item has an id or it doesn't exist in the Map
      r.set(o.label, o) // add it to the Map and return the Map
      :
      r // just return the Map
  , new Map()
).values()); // convert to an iterator

console.log(result);


Source: stackoverflow