Reputation: 2675
I have two arrays. I merge it and remove duplicates. Merging is done by taking into consideration all keys of the arrays (all key values in the object in array 1 must match with those in array 2).
var result1 = [{
name: 'Sandra',
email: '[email protected]'
},
{
name: 'John',
email: '[email protected]'
},
{
name: 'Peter',
email: '[email protected]'
},
{
name: 'Bobby',
email: '[email protected]'
},
{
name: 'Arun',
email: '[email protected]'
},
];
var result2 = [{
name: 'John',
email: '[email protected]'
},
{
name: 'Bobby',
email: '[email protected]'
},
{
name: 'Arun',
email: '[email protected]'
}
];
var result= _.uniqWith(_.concat(result1, result2), _.isEqual)
Now I need to check each item of merged array with each item of array1 and array2 and update the merged array if they are present or not.
So my end result should be like this.
var result = [{
name: 'Sandra',
email: '[email protected]',
presentInA: true,
presentInB: false
},
{
name: 'John',
email: '[email protected]',
presentInA: true,
presentInB: true
},
{
name: 'Peter',
email: '[email protected]',
presentInA: true,
presentInB: false
},
{
name: 'Bobby',
email: '[email protected]',
presentInA: true,
presentInB: true
},
{
name: 'Arun',
email: '[email protected]',
presentInA: false,
presentInB: true
},
{
name: 'Arun',
email: '[email protected]',
presentInA: true,
presentInB: false
}
];
How do I go about doing this in the best way? I think I can do it with iterating through all 3 arrays, but its a bad way of doing that.
Please advice.
Upvotes: 1
Views: 147
Reputation: 138437
You could use a hashtable for finding & merging dupes:
// Merges objects with the same name and email, sets the [arrName] property of the merged object to true
// also takes an optional settings object for chaining
function merge(arr, arrName, { hash = {}, result = [] } = {}) {
for(const { name, email } of arr) {
// Build up a hopefully unique key
const key = name + "@" + email;
// If its not in the hash yet, add it to the hash and the result
if(!hash[key])
result.push(hash[key] = { name, email });
// then set the key
hash[key][arrName] = true;
}
// allow chaining by exposing both hash and result
return { hash, result, merge: (arr, arrName) => merge(arr, arrName, { hash, result }) };
}
That could be used as:
const { result } = merge(result1, "presentInA").merge(result2, "presentInB");
That is O(n) but assumes that emails do not contain two @s.
Upvotes: 1
Reputation: 385
You can do something like this
result.map(
per => ({
name: per.name,
email: per.email,
presentInA: _.find(
result1, (o) => o.nombre === per.nombre && o.email === per.email
) ? true : false,
presentInB: _.find(
result2, (o) => o.nombre === per.nombre && o.email === per.email
) ? true : false,
})
)
Upvotes: 2
Reputation: 14968
You could iterate over result
and use _.some
in order to check whether each object inside it is in result1
and result2
(and set the corresponding properties presentInA
and presentInB
). Something like this:
_.forEach(result, (obj) => {
let presentInA = _.some(result1, obj);
let presentInB = _.some(result2, obj);
obj.presentInA = presentInA;
obj.presentInB = presentInB;
});
var result1 = [{
name: 'Sandra',
email: '[email protected]'
},
{
name: 'John',
email: '[email protected]'
},
{
name: 'Peter',
email: '[email protected]'
},
{
name: 'Bobby',
email: '[email protected]'
},
];
var result2 = [{
name: 'John',
email: '[email protected]'
},
{
name: 'Bobby',
email: '[email protected]'
},
{
name: 'Arun',
email: '[email protected]'
}
];
var result = _.uniqWith(_.concat(result1, result2), _.isEqual);
_.forEach(result, (obj) => {
let presentInA = _.some(result1, obj);
let presentInB = _.some(result2, obj);
obj.presentInA = presentInA;
obj.presentInB = presentInB;
});
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
Upvotes: 2