Presume these two ordered sequences:
var outer = new char[] { 'a', 'b', 'b', 'c', 'd', 'd', 'e' };
var inner = new char[] { 'a', 'b', 'c', 'c', 'd', 'd' };
Knowing that elements from both sequences are ordered, how can they be inner-joined more efficiently than with Enumerable.Join to produce the following sequence of tuples?
{ 'a', 'a' }
{ 'b', 'b' }
{ 'b', 'b' }
{ 'c', 'c' }
{ 'c', 'c' }
{ 'd', 'd' }
{ 'd', 'd' }
{ 'd', 'd' }
{ 'd', 'd' }
Notice that, unlike with Enumerable.Intersect that produces only distinct elements from both sequences, the output sequence here returns tuples that represent every combination of elements from a one-to-one, one-to-many or many-to-many relationship.
The semantics are much the same as INNER JOIN in SQL Server. But, more specifically, I'm looking for a C# implementation with the performance characteristics of the merge join algorithm (INNER MERGE JOIN) that returns an IEnumerable with deferred execution.
The required method signature might look something like this:
IEnumerable<TResult> MergeJoin<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner, TResult> resultSelector)