6

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.

2 Answers 2

11

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;
}, []);
Sign up to request clarification or add additional context in comments.

1 Comment

Awsome solution :)
4

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>

2 Comments

Also a great solution, thanks. I should get more accustomed to using the spread operator.
If large data set I believe this would be more performant than using nested find()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.