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.
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.
CodePudding user response:
Instead of _.unionBy
you can use _.unionWith
which accepts a custom comparator. The logic for comparison is:
- Compare by ID if both items have an ID.
- Compare by type if both items do not have an ID.
- 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/[email protected]/lodash.min.js"></script>