dextercom
dextercom

Reputation: 162

Remove 'duplicate' objects from array by comparing sub properties (typescript)

I receive an array of complex objects from the server. I would like to filter the original array to get a new array with unique objects by a sub-property of an each object, i.e :

let arr1 = originalArray;
let arr2 = originalArray.filter((ele, idx, arr) => ....

Now for example, arr1 consists of 3 objects:

firstObj = {
    id: 0,
    Details:
        {
            License: 123456
        },
    name: 'abc'
};
secondObj = {
    id: 1,
    Details:
        {
            License: 131313
        },
    name: 'xcd'
};
thirdObj = {
    id: 2,
    Details:
        {
            License: 123456
        },
    name: 'bcd'
};

So, I want to filter the array so that the newly returned array will consist of only two objects where the 'License' property will be unique, that is, one of the objects with the same 'License' will be removed. Thanks.

Upvotes: 6

Views: 7622

Answers (2)

charlietfl
charlietfl

Reputation: 171669

If order they occur is not important can pass them into a Map using Licence values as keys.

Map keys must be unique so this will overwrite duplicates as they occur while creating the Map and return last instance of each duplicate

let uniques = [...new Map(data.map(o=>[o.Details.License,o])).values()];


console.log(uniques)
<script>
let data = [{
  id: 0,
  Details: {
    License: 123456
  },
  name: 'abc'
}, {
  id: 1,
  Details: {
    License: 131313
  },
  name: 'xcd'
}, {
  id: 2,
  Details: {
    License: 123456
  },
  name: 'bcd'
}]
</script>


Alternate approach using Array#filter and a Set to track unique values

let licSet = new Set();
let uniques = data.filter(({Details: o}) => !licSet.has(o.License) && licSet.add(o.License));


console.log(uniques)
<script>
  let data = [{
    id: 0,
    Details: {
      License: 123456
    },
    name: 'abc'
  }, {
    id: 1,
    Details: {
      License: 131313
    },
    name: 'xcd'
  }, {
    id: 2,
    Details: {
      License: 123456
    },
    name: 'bcd'
  }]
</script>

Upvotes: 4

mickl
mickl

Reputation: 49955

You can use array.reduce to loop through source array and add items to result if it does not contain same Details.License

let result = [firstObj, secondObj, thirdObj].reduce((arr, item) => {
    let exists = !!arr.find(x => x.Details.License === item.Details.License);
    if(!exists){
        arr.push(item);
    }
    return arr;
}, []);

Upvotes: 11

Related Questions