Reputation: 12368
Consider two lists of complex objects say :
var first = new List<Record>
{
new Record(1, new List<int> { 2, 3 }),
new Record(4, new List<int> { 5, 6 })
};
var second = new List<Record>
{
new Record(1, new List<int> { 4 })
};
where a Record
is defined as below. Nothing fancy, just a class with Id
and list of
SecondaryIdentifiers
.
public class Record
{
private readonly IList<int> _secondaryIdentifiers;
private readonly int _id;
public Record(int id, IList<int> secondaryIdentifiers)
{
_id = id;
_secondaryIdentifiers = secondaryIdentifiers;
}
public IList<int> SecondaryIdentifiers
{
get { return _secondaryIdentifiers; }
}
public int Id
{
get { return _id; }
}
}
How can I union / interest such that the Union and Intersect operations merge the SecondaryIdentifiers.
var union = first.Union(second);
var intersect = first.Intersect(second);
Union will be
{
new Record(1, new List<int> { 2, 3 , 4 }),
new Record(4, new List<int> { 5, 6 })
};
Intersect will be
{
new Record(1, new List<int> { 2, 3 , 4 }),
};
What I have tried
I tried using a first.Union(second, new EqualityComparer())
where the EqualityComparer
extends IEqualityComparer<Record>
and merges the two SecondaryIdentifiers
if the two items compared are equal, but it seemed a little hacky to me.
Is there a more elegant way of doing this ?
Upvotes: 1
Views: 2160
Reputation: 5301
this should work for the union part:
from a in first
join b in second on a.Id equals b.Id into rGroup
let ids = a.SecondaryIdentifiers.Union(rGroup.SelectMany(r => r.SecondaryIdentifiers))
select new Record(a.Id, ids.ToList())
and the intersect:
from a in first
join b in second on a.Id equals b.Id
select new Record(a.Id, a.SecondaryIdentifiers.Union(b.SecondaryIdentifiers).ToList())
Upvotes: 0
Reputation: 116108
Is there a more elegant way of doing this
It is opinion based but I would do it as:
var union = first.Concat(second)
.GroupBy(x => x.Id)
.Select(g => g.SelectMany(y => y.SecondaryIdentifiers).ToList())
.ToList();
var intersect = first.Concat(second)
.GroupBy(x => x.Id)
.Where(x => x.Count() > 1)
.Select(g => g.SelectMany(y => y.SecondaryIdentifiers).ToList())
.ToList();
PS: Feel free to remove .ToList()
s for lazy evaluation.
Upvotes: 2