I needed an implementation on Union that compares a property of an object, rather the objects themselves. I came up with the following:
public static IEnumerable<TSource> UnionBy<TSource, TKey>(
this IEnumerable<TSource> first,
IEnumerable<TSource> second,
Func<TSource, TKey> keySelector,
IEqualityComparer<TKey> keyComparer = null)
{
HashSet<TKey> keys = new HashSet<TKey>(keyComparer);
foreach (TSource element in first)
{
if (keys.Add(keySelector(element)))
{
yield return element;
}
}
foreach (TSource element in second)
{
if (!keys.Add(keySelector(element)))
{
continue;
}
yield return element;
}
}
which I can use by saying something along the lines of:
result = first.UnionBy(second, x => x.Property1);
Which works for me, but I was wondering if there wasn't something already implemented in Linq that I was missing (other than implementing my own EqualityComparer which to me seems less intuitive).
Since I won't be using the same properties every time I want this union I would either have to make multiple EqualityComparer
's for each situation which doesn't seem correct to me, or make some generic EqualityComparer
that would take in a property selector Func. It seemed less intuitive to me than just providing a generic Linq extension that accepted the property selector itself.
Yes you can write it as follows instead:
var q = first.Concat(second).GroupBy(x => x.Property1).Select(x => x.First());