Method FullOuterMergeJoin
| Edit this page View SourceFullOuterMergeJoin<TLeft, TRight, TKey>(IEnumerable<TLeft>, IEnumerable<TRight>, Func<TLeft, TKey>, Func<TRight, TKey>, IComparer<TKey>?)
Performs a full outer join on two heterogeneous sequences.
Declaration
public static IEnumerable<(TLeft? Left, TRight? Right)> FullOuterMergeJoin<TLeft, TRight, TKey>(this IEnumerable<TLeft> left, IEnumerable<TRight> right, Func<TLeft, TKey> leftKeySelector, Func<TRight, TKey> rightKeySelector, IComparer<TKey>? comparer = null)
Parameters
Type | Name | Description |
---|---|---|
IEnumerable<TLeft> | left | The first sequence. |
IEnumerable<TRight> | right | The second sequence. |
Func<TLeft, TKey> | leftKeySelector | A function to extract the join key from each element of the first sequence. |
Func<TRight, TKey> | rightKeySelector | A function to extract the join key from each element of the second sequence. |
IComparer<TKey> | comparer | An IEqualityComparer<T> to hash and compare keys. |
Returns
Type | Description |
---|---|
IEnumerable<(TLeft Left, TRight Right)> | A sequence containing values from a full outer join of the two input sequences. |
Type Parameters
Name | Description |
---|---|
TLeft | The type of elements in the first sequence. |
TRight | The type of elements in the second sequence. |
TKey | The type of the key returned by the key selector functions. |
Remarks
The result of this method is a `full outer`-join. All elements from both left
and
right
are returned; matching elements are returned together, and elements that do not
match are returned with a default value for the other.
This method is implemented using a `merge`-join. The sequences left
and right
are assumed to be already sorted. Results from using unsorted sequences with this method are
undefined. Each sequence is enumerated exactly once in a parallel fashion, until both sequences are
fully enumerated.
This method uses deferred execution and streams its results.
Examples
The following code example demonstrates how to execute an full outer merge join of two sequences using FullOuterMergeJoin
.
var people = new Person[]
{
new("John Doe", 1),
new("Jane Doe", 6),
new("Lucy Ricardo", 4),
new("Ricky Ricardo", 2),
new("Fred Mertz", 3),
new("Ethel Mertz", 5),
};
var pets = new Pet[]
{
new("Bear", 8),
new("Polly", 2),
new("Minnie", 2),
new("Mittens", 1),
new("Patches", 1),
new("Paws", 1),
};
var results = people.OrderBy(p => p.PersonId)
.FullOuterMergeJoin(
pets.OrderBy(p => p.PersonId),
p => p.PersonId,
p => p.PersonId);
foreach (var (person, pet) in results)
{
Console.WriteLine($"({person?.Name ?? "N/A"}, {pet?.Name ?? "No Pets"})");
}
// This code produces the following output:
// (John Doe, Mittens)
// (John Doe, Patches)
// (John Doe, Paws)
// (Jane Doe, No Pets)
// (Lucy Ricardo, No Pets)
// (Ricky Ricardo, Polly)
// (Ricky Ricardo, Minnie)
// (Fred Mertz, No Pets)
// (Ethel Mertz, No Pets)
// (N/A, Bear)
record Person(string Name, int PersonId);
record Pet(string Name, int PersonId);
Exceptions
Type | Condition |
---|---|
ArgumentNullException |
|
FullOuterMergeJoin<TLeft, TRight, TKey, TResult>(IEnumerable<TLeft>, IEnumerable<TRight>, Func<TLeft, TKey>, Func<TRight, TKey>, Func<TLeft, TResult>, Func<TRight, TResult>, Func<TLeft, TRight, TResult>, IComparer<TKey>?)
Performs a full outer join on two heterogeneous sequences.
Declaration
public static IEnumerable<TResult> FullOuterMergeJoin<TLeft, TRight, TKey, TResult>(this IEnumerable<TLeft> left, IEnumerable<TRight> right, Func<TLeft, TKey> leftKeySelector, Func<TRight, TKey> rightKeySelector, Func<TLeft, TResult> leftResultSelector, Func<TRight, TResult> rightResultSelector, Func<TLeft, TRight, TResult> bothResultSelector, IComparer<TKey>? comparer = null)
Parameters
Type | Name | Description |
---|---|---|
IEnumerable<TLeft> | left | The first sequence. |
IEnumerable<TRight> | right | The second sequence. |
Func<TLeft, TKey> | leftKeySelector | A function to extract the join key from each element of the first sequence. |
Func<TRight, TKey> | rightKeySelector | A function to extract the join key from each element of the second sequence. |
Func<TLeft, TResult> | leftResultSelector | A function to create a result element from a |
Func<TRight, TResult> | rightResultSelector | A function to create a result element from a |
Func<TLeft, TRight, TResult> | bothResultSelector | A function to create a result element from two matching elements. |
IComparer<TKey> | comparer | An IEqualityComparer<T> to hash and compare keys. |
Returns
Type | Description |
---|---|
IEnumerable<TResult> | A sequence containing values projected from a right outer join of the two input sequences. |
Type Parameters
Name | Description |
---|---|
TLeft | The type of elements in the first sequence. |
TRight | The type of elements in the second sequence. |
TKey | The type of the key returned by the key selector functions. |
TResult | The type of the result elements. |
Remarks
The result of this method is a `full outer`-join. Values are projected using bothResultSelector
when matching elements are found in both left
and right
sequences. Values are projected using leftKeySelector
when elements in
left
do not have a matching element in right
. Values are projected
using rightResultSelector
when elements in right
do not have a
matching element in left
.
This method is implemented using a `merge`-join. The sequences left
and right
are assumed to be already sorted. Results from using unsorted sequences with this method are
undefined. Each sequence is enumerated exactly once in a parallel fashion, until both sequences are
fully enumerated.
This method uses deferred execution and streams its results.
Examples
The following code example demonstrates how to execute an full outer merge join of two sequences using FullOuterMergeJoin
.
var people = new Person[]
{
new("John Doe", 1),
new("Jane Doe", 6),
new("Lucy Ricardo", 4),
new("Ricky Ricardo", 2),
new("Fred Mertz", 3),
new("Ethel Mertz", 5),
};
var pets = new Pet[]
{
new("Bear", 8),
new("Polly", 2),
new("Minnie", 2),
new("Mittens", 1),
new("Patches", 1),
new("Paws", 1),
};
var results = people.OrderBy(p => p.PersonId)
.FullOuterMergeJoin(
pets.OrderBy(p => p.PersonId),
p => p.PersonId,
p => p.PersonId,
person => $"({person.Name}, No Pets)",
pet => $"(N/A, {pet.Name})",
(person, pet) => $"({person.Name}, {pet.Name})");
foreach (var str in results)
Console.WriteLine(str);
// This code produces the following output:
// (John Doe, Mittens)
// (John Doe, Patches)
// (John Doe, Paws)
// (Jane Doe, No Pets)
// (Lucy Ricardo, No Pets)
// (Ricky Ricardo, Polly)
// (Ricky Ricardo, Minnie)
// (Fred Mertz, No Pets)
// (Ethel Mertz, No Pets)
// (N/A, Bear)
record Person(string Name, int PersonId);
record Pet(string Name, int PersonId);
Exceptions
Type | Condition |
---|---|
ArgumentNullException |
|