Method FullGroupJoin
| Edit this page View SourceFullGroupJoin<TFirst, TSecond, TKey>(IEnumerable<TFirst>, IEnumerable<TSecond>, Func<TFirst, TKey>, Func<TSecond, TKey>)
Performs a Full Group Join between the first
and second
sequences.
Declaration
public static IEnumerable<(TKey Key, IEnumerable<TFirst> First, IEnumerable<TSecond> Second)> FullGroupJoin<TFirst, TSecond, TKey>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TKey> firstKeySelector, Func<TSecond, TKey> secondKeySelector)
Parameters
Type | Name | Description |
---|---|---|
IEnumerable<TFirst> | first | First sequence |
IEnumerable<TSecond> | second | Second sequence |
Func<TFirst, TKey> | firstKeySelector | The mapping from first sequence to key |
Func<TSecond, TKey> | secondKeySelector | The mapping from second sequence to key |
Returns
Type | Description |
---|---|
IEnumerable<(TKey Key, IEnumerable<TFirst> First, IEnumerable<TSecond> Second)> | A sequence of elements joined from |
Type Parameters
Name | Description |
---|---|
TFirst | The type of the elements in the first input sequence |
TSecond | The type of the elements in the second input sequence |
TKey | The type of the key to use to join |
Remarks
This operator uses deferred execution and streams the results. The results are yielded in the order of the elements found in the first sequence followed by those found only in the second. In addition, the callback responsible for projecting the results is supplied with sequences which preserve their source order.
Examples
The following code example demonstrates how to execute a full group join using FullGroupJoin
var people = new Person[]
{
new("John Doe", 1),
new("Jane Doe", 1),
new("Lucy Ricardo", 2),
new("Ricky Ricardo", 2),
new("Fred Mertz", 3),
new("Ethel Mertz", 3),
};
var pets = new Pet[]
{
new("Bear", 3),
new("Polly", 2),
new("Minnie", 2),
new("Mittens", 1),
new("Patches", 1),
new("Paws", 1),
};
var results = people
.FullGroupJoin(
pets,
p => p.FamilyId,
p => p.FamilyId);
foreach (var (familyId, familyPeople, familyPets) in results)
{
var str1 = string.Join(", ", familyPeople.Select(p => p.Name));
var str2 = string.Join(", ", familyPets.Select(p => p.Name));
Console.WriteLine($"({familyId}, [{str1}], [{str2}])");
}
// This code produces the following output:
// (1, [John Doe, Jane Doe], [Mittens, Patches, Paws])
// (2, [Lucy Ricardo, Ricky Ricardo], [Polly, Minnie])
// (3, [Fred Mertz, Ethel Mertz], [Bear])
record Person(string Name, int FamilyId);
record Pet(string Name, int FamilyId);
Exceptions
Type | Condition |
---|---|
ArgumentNullException |
|
FullGroupJoin<TFirst, TSecond, TKey>(IEnumerable<TFirst>, IEnumerable<TSecond>, Func<TFirst, TKey>, Func<TSecond, TKey>, IEqualityComparer<TKey>?)
Performs a Full Group Join between the first
and second
sequences.
Declaration
public static IEnumerable<(TKey Key, IEnumerable<TFirst> First, IEnumerable<TSecond> Second)> FullGroupJoin<TFirst, TSecond, TKey>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TKey> firstKeySelector, Func<TSecond, TKey> secondKeySelector, IEqualityComparer<TKey>? comparer)
Parameters
Type | Name | Description |
---|---|---|
IEnumerable<TFirst> | first | First sequence |
IEnumerable<TSecond> | second | Second sequence |
Func<TFirst, TKey> | firstKeySelector | The mapping from first sequence to key |
Func<TSecond, TKey> | secondKeySelector | The mapping from second sequence to key |
IEqualityComparer<TKey> | comparer | The equality comparer to use to determine whether or not keys are equal. If null, the
default equality comparer for |
Returns
Type | Description |
---|---|
IEnumerable<(TKey Key, IEnumerable<TFirst> First, IEnumerable<TSecond> Second)> | A sequence of elements joined from |
Type Parameters
Name | Description |
---|---|
TFirst | The type of the elements in the first input sequence |
TSecond | The type of the elements in the second input sequence |
TKey | The type of the key to use to join |
Remarks
This operator uses deferred execution and streams the results. The results are yielded in the order of the elements found in the first sequence followed by those found only in the second. In addition, the callback responsible for projecting the results is supplied with sequences which preserve their source order.
Examples
The following code example demonstrates how to execute a full group join using FullGroupJoin
var people = new Person[]
{
new("John Doe", 1),
new("Jane Doe", 1),
new("Lucy Ricardo", 2),
new("Ricky Ricardo", 2),
new("Fred Mertz", 3),
new("Ethel Mertz", 3),
};
var pets = new Pet[]
{
new("Bear", 103),
new("Polly", 102),
new("Minnie", 102),
new("Mittens", 101),
new("Patches", 101),
new("Paws", 101),
};
var results = people
.FullGroupJoin(
pets,
p => p.FamilyId,
p => p.FamilyId,
new IntBy100Comparer());
foreach (var (familyId, familyPeople, familyPets) in results)
{
var str1 = string.Join(", ", familyPeople.Select(p => p.Name));
var str2 = string.Join(", ", familyPets.Select(p => p.Name));
Console.WriteLine($"({familyId}, [{str1}], [{str2}])");
}
// This code produces the following output:
// (1, [John Doe, Jane Doe], [Mittens, Patches, Paws])
// (2, [Lucy Ricardo, Ricky Ricardo], [Polly, Minnie])
// (3, [Fred Mertz, Ethel Mertz], [Bear])
record Person(string Name, int FamilyId);
record Pet(string Name, int FamilyId);
class IntBy100Comparer : IEqualityComparer<int>
{
public bool Equals(int x, int y) =>
x % 100 == y % 100;
public int GetHashCode(int obj) =>
(obj % 100).GetHashCode();
}
Exceptions
Type | Condition |
---|---|
ArgumentNullException |
|
FullGroupJoin<TFirst, TSecond, TKey, TResult>(IEnumerable<TFirst>, IEnumerable<TSecond>, Func<TFirst, TKey>, Func<TSecond, TKey>, Func<TKey, IEnumerable<TFirst>, IEnumerable<TSecond>, TResult>)
Performs a full group-join between two sequences.
Declaration
public static IEnumerable<TResult> FullGroupJoin<TFirst, TSecond, TKey, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TKey> firstKeySelector, Func<TSecond, TKey> secondKeySelector, Func<TKey, IEnumerable<TFirst>, IEnumerable<TSecond>, TResult> resultSelector)
Parameters
Type | Name | Description |
---|---|---|
IEnumerable<TFirst> | first | First sequence |
IEnumerable<TSecond> | second | Second sequence |
Func<TFirst, TKey> | firstKeySelector | The mapping from first sequence to key |
Func<TSecond, TKey> | secondKeySelector | The mapping from second sequence to key |
Func<TKey, IEnumerable<TFirst>, IEnumerable<TSecond>, TResult> | resultSelector | Function to apply to each pair of elements plus the key |
Returns
Type | Description |
---|---|
IEnumerable<TResult> | A sequence of elements joined from |
Type Parameters
Name | Description |
---|---|
TFirst | The type of the elements in the first input sequence |
TSecond | The type of the elements in the second input sequence |
TKey | The type of the key to use to join |
TResult | The type of the elements of the resulting sequence |
Remarks
This operator uses deferred execution and streams the results. The results are yielded in the order of the elements found in the first sequence followed by those found only in the second. In addition, the callback responsible for projecting the results is supplied with sequences which preserve their source order.
Examples
The following code example demonstrates how to execute a full group join using FullGroupJoin
var people = new Person[]
{
new("John Doe", 1),
new("Jane Doe", 1),
new("Lucy Ricardo", 2),
new("Ricky Ricardo", 2),
new("Fred Mertz", 3),
new("Ethel Mertz", 3),
};
var pets = new Pet[]
{
new("Bear", 3),
new("Polly", 2),
new("Minnie", 2),
new("Mittens", 1),
new("Patches", 1),
new("Paws", 1),
};
var results = people
.FullGroupJoin(
pets,
p => p.FamilyId,
p => p.FamilyId,
(familyId, familyPeople, familyPets) =>
{
var str1 = string.Join(", ", familyPeople.Select(p => p.Name));
var str2 = string.Join(", ", familyPets.Select(p => p.Name));
return $"({familyId}, [{str1}], [{str2}])";
});
foreach (var str in results)
Console.WriteLine(str);
// This code produces the following output:
// (1, [John Doe, Jane Doe], [Mittens, Patches, Paws])
// (2, [Lucy Ricardo, Ricky Ricardo], [Polly, Minnie])
// (3, [Fred Mertz, Ethel Mertz], [Bear])
record Person(string Name, int FamilyId);
record Pet(string Name, int FamilyId);
Exceptions
Type | Condition |
---|---|
ArgumentNullException |
|
FullGroupJoin<TFirst, TSecond, TKey, TResult>(IEnumerable<TFirst>, IEnumerable<TSecond>, Func<TFirst, TKey>, Func<TSecond, TKey>, Func<TKey, IEnumerable<TFirst>, IEnumerable<TSecond>, TResult>, IEqualityComparer<TKey>?)
Performs a full group-join between two sequences.
Declaration
public static IEnumerable<TResult> FullGroupJoin<TFirst, TSecond, TKey, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TKey> firstKeySelector, Func<TSecond, TKey> secondKeySelector, Func<TKey, IEnumerable<TFirst>, IEnumerable<TSecond>, TResult> resultSelector, IEqualityComparer<TKey>? comparer)
Parameters
Type | Name | Description |
---|---|---|
IEnumerable<TFirst> | first | First sequence |
IEnumerable<TSecond> | second | Second sequence |
Func<TFirst, TKey> | firstKeySelector | The mapping from first sequence to key |
Func<TSecond, TKey> | secondKeySelector | The mapping from second sequence to key |
Func<TKey, IEnumerable<TFirst>, IEnumerable<TSecond>, TResult> | resultSelector | Function to apply to each pair of elements plus the key |
IEqualityComparer<TKey> | comparer | The equality comparer to use to determine whether or not keys are equal. If null, the
default equality comparer for |
Returns
Type | Description |
---|---|
IEnumerable<TResult> | A sequence of elements joined from |
Type Parameters
Name | Description |
---|---|
TFirst | The type of the elements in the first input sequence |
TSecond | The type of the elements in the second input sequence |
TKey | The type of the key to use to join |
TResult | The type of the elements of the resulting sequence |
Remarks
This operator uses deferred execution and streams the results. The results are yielded in the order of the elements found in the first sequence followed by those found only in the second. In addition, the callback responsible for projecting the results is supplied with sequences which preserve their source order.
Examples
The following code example demonstrates how to execute a full group join using FullGroupJoin
var people = new Person[]
{
new("John Doe", 1),
new("Jane Doe", 1),
new("Lucy Ricardo", 2),
new("Ricky Ricardo", 2),
new("Fred Mertz", 3),
new("Ethel Mertz", 3),
};
var pets = new Pet[]
{
new("Bear", 103),
new("Polly", 102),
new("Minnie", 102),
new("Mittens", 101),
new("Patches", 101),
new("Paws", 101),
};
var results = people
.FullGroupJoin(
pets,
p => p.FamilyId,
p => p.FamilyId,
(familyId, familyPeople, familyPets) =>
{
var str1 = string.Join(", ", familyPeople.Select(p => p.Name));
var str2 = string.Join(", ", familyPets.Select(p => p.Name));
return $"({familyId}, [{str1}], [{str2}])";
},
new IntBy100Comparer());
foreach (var str in results)
Console.WriteLine(str);
// This code produces the following output:
// (1, [John Doe, Jane Doe], [Mittens, Patches, Paws])
// (2, [Lucy Ricardo, Ricky Ricardo], [Polly, Minnie])
// (3, [Fred Mertz, Ethel Mertz], [Bear])
record Person(string Name, int FamilyId);
record Pet(string Name, int FamilyId);
class IntBy100Comparer : IEqualityComparer<int>
{
public bool Equals(int x, int y) =>
x % 100 == y % 100;
public int GetHashCode(int obj) =>
(obj % 100).GetHashCode();
}
Exceptions
Type | Condition |
---|---|
ArgumentNullException |
|