Created
August 8, 2018 03:23
-
-
Save joshkel/303a2d89c8112d6dca0f07f3b64a6543 to your computer and use it in GitHub Desktop.
LeftJoin using a generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Based on https://gist.github.com/reidev275/f765c506aea0e3e3432da591b2c30c15#file-leftJoin-cs | |
public struct Join<A, B> | |
{ | |
public A First { get; set; } | |
public B Second { get; set; } | |
} | |
public static IEnumerable<Join<A, B>> LeftJoin2<A, B, C>(this IEnumerable<A> from, IEnumerable<B> join, | |
Func<A, C> onFrom, Func<B, C> onJoin) where C : IComparable<C> | |
{ | |
var fromS = from.OrderBy(onFrom); | |
using (var fromE = fromS.GetEnumerator()) | |
{ | |
if (!fromE.MoveNext()) | |
{ | |
yield break; | |
} | |
var joinS = join.OrderBy(onJoin); | |
using (var joinE = joinS.GetEnumerator()) | |
{ | |
if (!joinE.MoveNext()) | |
{ | |
do | |
{ | |
yield return new Join<A, B> {First = fromE.Current, Second = default(B)}; | |
} while (fromE.MoveNext()); | |
yield break; | |
} | |
var match = false; | |
while (true) | |
{ | |
var key = onFrom(fromE.Current); | |
var b = onJoin(joinE.Current); | |
var comp = key.CompareTo(b); | |
switch (comp) | |
{ | |
case -1: | |
if (!match) yield return new Join<A, B> {First = fromE.Current, Second = default(B)}; | |
if (!fromE.MoveNext()) | |
{ | |
yield break; | |
} | |
match = false; | |
break; | |
case 1: | |
if (!joinE.MoveNext()) | |
{ | |
while (fromE.MoveNext()) | |
{ | |
yield return new Join<A, B> {First = fromE.Current, Second = default(B)}; | |
} | |
yield break; | |
} | |
match = false; | |
break; | |
default: | |
yield return new Join<A, B> {First = fromE.Current, Second = joinE.Current}; | |
match = true; | |
if (!joinE.MoveNext()) | |
{ | |
while (fromE.MoveNext()) | |
{ | |
yield return new Join<A, B> {First = fromE.Current, Second = default(B)}; | |
} | |
yield break; | |
} | |
break; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment