Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Merge multiple object arrays and removing duplicates based on optional property

Say if there are arrays like:

const arr1 = [
   { "id": "1", "type": "sales" },
   { "id": "2", "type": "finance" }
]

const arr2 = [
   { "type": "sales" },
   { "id": "2", "type": "finance" }
]

const arr3 = [
   { "id": "1", "type": "sales" },
   { "type": "sales" },
   { "type": "finance" }
]

As you can see, id is optional. I need to merge arrays in such way that uniqueness should be based on id if present, else entire rest of the object.
ex. here merged array would be:

[ 
  { "id": "1", "type": "sales" }, 
  { "type": "sales" }, 
  { "id": "2", "type": "finance" }, 
  { "type": "finance" } 
]

loadash has .unionBy but optional uniqueness doesn’t work.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const result = _.unionBy(arr1, arr2, arr3, 'id')

Probably I have to iterate through each, but I was wondering if there is any simpler alternative for this.

>Solution :

Instead of _.unionBy you can use _.unionWith which accepts a custom comparator. The logic for comparison is:

  1. Compare by ID if both items have an ID.
  2. Compare by type if both items do not have an ID.
  3. Consider them different if one has an ID the other not.
const arr1 = [
   { "id": "1", "type": "sales" },
   { "id": "2", "type": "finance" }
]

const arr2 = [
   { "type": "sales" },
   { "id": "2", "type": "finance" }
]

const arr3 = [
   { "id": "1", "type": "sales" },
   { "type": "sales" },
   { "type": "finance" }
]

const result = _.unionWith(arr1, arr2, arr3, (item1, item2) => {
  const item1HasId = _.has(item1, "id");
  const item2HasId = _.has(item2, "id");
  
  if (item1HasId && item2HasId) //if both have ID...
    return item1.id === item2.id; // ...compare by ID
    
  if (!item1HasId && !item2HasId) //if neither has ID...
    return item1.type === item2.type; // ...compare by type
    
  return false; // otherwise not equal
});

console.log(result);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading