2

Note: This is not a duplicate question, as the elements are all unique. If the elements were the same I wouldn't have asked. I am talking about a single key values...

I'm trying to find an efficient way to remove elements with a duplicate key-value pair from an array of unique objects except first such one. i.e.

Let's say I have an array of object like below:

    const array = [
        { checkID: 'aaa', animal: 'cat'},
        { checkID: 'bbb', animal: 'dog'},
        { checkID: 'ccc', animal: 'monkey'},
        { checkID: 'ddd', animal: 'horse'},
        { checkID: 'eee', animal: 'cow'},
        { checkID: 'fff', animal: 'cat'}
    ]

Here is the logic:

  1. The target key is 'animal'
  2. If there is no other element with the same value for the field, keep it.
  3. If there are duplicate elements with the same value for the field but it is the first one, keep it.
  4. If there are duplicate elements with the same value for the field and it is not the first one, delete it.

As a result, the array should be:

    const result = [
        { checkID: 'aaa', animal: 'cat'},
        { checkID: 'bbb', animal: 'dog'},
        { checkID: 'ccc', animal: 'monkey'},
        { checkID: 'ddd', animal: 'horse'},
        { checkID: 'eee', animal: 'cow'}
    ]

The elements are unique and it makes the job complicated. Tried creating a separate array with the 'animal' values and then using the filter method but the code got messy and thought there might be a better way.

Any suggestions? Thanks

J.Ko
  • 6,561
  • 3
  • 12
  • 28

2 Answers2

1

You can use a map to filter out the duplicate as follows:

const array = [ { checkID: 'aaa', animal: 'cat'}, { checkID: 'bbb', animal: 'dog'}, { checkID: 'ccc', animal: 'monkey'}, { checkID: 'ddd', animal: 'horse'}, { checkID: 'eee', animal: 'cow'}, { checkID: 'fff', animal: 'cat'} ];

const unique = [...
  array.reduce((map, obj) => {
    if(!map.has(obj.animal)) map.set(obj.animal, obj);
    return map;
  }, new Map)
  .values()
];

console.log(unique);
Majed Badawi
  • 27,616
  • 4
  • 25
  • 48
1

You could take a Set in a closure with the wanted key for filtering.

const
    uniqueBy = (k, s = new Set) => o => !s.has(o[k]) && s.add(o[k]),
    array = [{ checkID: 'aaa', animal: 'cat' }, { checkID: 'bbb', animal: 'dog' }, { checkID: 'ccc', animal: 'monkey' }, { checkID: 'ddd', animal: 'horse' }, { checkID: 'eee', animal: 'cow' }, { checkID: 'fff', animal: 'cat' }],
    result = array.filter(uniqueBy('animal'));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392