Based on the referenced answer I tried something that doesn’t create Lookup
‘s but Dictionary
‘s instead.
IMHO that’s the only thing you can cut that will actually save some time.
Skipping creation of the HashSet
(as proposed in my rushed comment) is not an option as this will lead to the duplication of all joined pairs.
public static class Extensions {
public static IEnumerable<TResult> FullOuterJoin<TA, TB, TKey, TResult>(
this IEnumerable<TA> a,
IEnumerable<TB> b,
Func<TA, TKey> selectKeyA,
Func<TB, TKey> selectKeyB,
Func<TA, TB, TKey, TResult> projection,
TA defaultA = default(TA),
TB defaultB = default(TB),
IEqualityComparer<TKey> cmp = null) {
cmp = cmp ?? EqualityComparer<TKey>.Default;
var adict = a.ToDictionary(selectKeyA, cmp);
var bdict = b.ToDictionary(selectKeyB, cmp);
var keys = new HashSet<TKey>(adict.Keys, cmp);
keys.UnionWith(bdict.Keys);
var join = from key in keys
let xa = adict.GetOrDefault(key, defaultA)
let xb = bdict.GetOrDefault(key, defaultB)
select projection(xa, xb, key);
return join;
}
public static T GetOrDefault<K, T>(this IDictionary<K, T> d, K k, T def = default(T))
=> d.TryGetValue(k, out T value) ? value : def;
}
1
solved Full outer Join in LINQ optimized for unique keys [closed]