diff --git a/MoreLinq.Test/BatchByTests.cs b/MoreLinq.Test/BatchByTests.cs new file mode 100644 index 000000000..26811acdf --- /dev/null +++ b/MoreLinq.Test/BatchByTests.cs @@ -0,0 +1,218 @@ +using NUnit.Framework.Interfaces; + +namespace MoreLinq.Test +{ + using System; + using System.Collections.Generic; + using NUnit.Framework; + + [TestFixture] + public class BatchByTests + { + public static readonly IEnumerable TestData = + from d in new[] + { + new { + s = new[] {"Q1", "Q2", "A1", "A2"}, + k = new[] {"Q", "A"}, + r = new[] { + new [] {("A", "A1"), ("Q", "Q1")}, + new [] {("A", "A2"), ("Q", "Q2")}}}, + new { + s = new[] {"Q1", "A1", "Q2", "A2"}, + k = new[] {"Q", "A"}, + r = new[] { + new [] {("A", "A1"), ("Q", "Q1")}, + new [] {("A", "A2"), ("Q", "Q2")}}}, + new { + s = new[] {"A1", "Q1", "Q2", "A2"}, + k = new[] {"Q", "A"}, + r = new[] { + new [] {("A", "A1"), ("Q", "Q1")}, + new [] {("A", "A2"), ("Q", "Q2")}}}, + new { + s = new[] {"Q1", "A1", "A2", "Q2"}, + k = new[] {"Q", "A"}, + r = new[] { + new [] {("A", "A1"), ("Q", "Q1")}, + new [] {("A", "A2"), ("Q", "Q2")}}}, + new { + s = new[] {"A1", "Q1", "A2", "Q2"}, + k = new[] {"Q", "A"}, + r = new[] { + new [] {("A", "A1"), ("Q", "Q1")}, + new [] {("A", "A2"), ("Q", "Q2")}}}, + new { + s = new[] {"A1", "A2", "Q1", "Q2"}, + k = new[] {"Q", "A"}, + r = new[] { + new [] {("A", "A1"), ("Q", "Q1")}, + new [] {("A", "A2"), ("Q", "Q2")}}}, + new { + s = new[] {"Q1", null, "A1", "#", "Q2", "A2"}, + k = new[] {"Q", "A"}, + r = new[] { + new [] {("A", "A1"), ("Q", "Q1")}, + new [] {("A", "A2"), ("Q", "Q2")}}}, + } + select new TestCaseData(d.s, d.k).Returns(d.r); + + + [Test, TestCaseSource(nameof(TestData))] + public (string Key, string Value)[][] BatchByOnKnownCase(string[] source, string[] acceptedKeys) + { + static string KeySelector(string s) => s?.FirstOrDefault().ToString(); + var equalityComparer = EqualityComparer.Default; + + return source.BatchBy(acceptedKeys, KeySelector, equalityComparer) + .Select(d => d.Select(kvp => (kvp.Key, kvp.Value)).OrderBy(kvp => kvp.Key).ToArray()) + .ToArray(); + } + + [Test] + public void BatchByDoNotEnumerateSourceOnEmptyAcceptedKeys() + { + var source = MoreEnumerable.From(() => throw new TestException()); + static string KeySelector(int i) => $"{i}"; + var acceptedKeys = Enumerable.Empty(); + var equalityComparer = EqualityComparer.Default; + + void Code() + { + source.BatchBy(acceptedKeys, KeySelector, equalityComparer); + } + + Assert.DoesNotThrow(Code); + } + + [Test] + public void BatchByDoNotReEnumerateSourceOnMultipleEnumeration() + { + var source = Enumerable.Range(0, 5); + static string KeySelector(int i) => $"{i}"; + var acceptedKeys = TestingSequence.Of("0", "1", "2", "3"); + var equalityComparer = EqualityComparer.Default; + + void Code() + { + var enumerable = source.BatchBy(acceptedKeys, KeySelector, equalityComparer); + enumerable.Consume(); + enumerable.Consume(); + } + + Assert.DoesNotThrow(Code); + } + + [Test] + public void BatchByDoNotThrowOnDuplicateAcceptedKeyAtCreation() + { + using var source = TestingSequence.Of(0, 1, 2, 3); + static string KeySelector(int i) => $"{i}"; + var acceptedKeys = TestingSequence.Of("0", "1", "1", "3"); + var equalityComparer = EqualityComparer.Default; + + void Code() + { + source.BatchBy(acceptedKeys, KeySelector, equalityComparer); + } + + Assert.DoesNotThrow(Code); + } + + [Test] + public void BatchByDoNotThrowOnNullAcceptedKeyAtCreation() + { + using var source = TestingSequence.Of(0, 1, 2, 3); + static string KeySelector(int i) => $"{i}"; + var acceptedKeys = TestingSequence.Of("0", "1", null, "3"); + var equalityComparer = EqualityComparer.Default; + + void Code() + { + source.BatchBy(acceptedKeys, KeySelector, equalityComparer); + } + + Assert.DoesNotThrow(Code); + } + + [Test] + public void BatchByDoNotThrowOnNullKeyFromKeySelector() + { + using var source = TestingSequence.Of(0, 1, 2, 3); + static string KeySelector(int i) => i == 0 ? null : $"{i}"; + var acceptedKeys = TestingSequence.Of("0", "1", "1", "3"); + var equalityComparer = EqualityComparer.Default; + + void Code() + { + source.BatchBy(acceptedKeys, KeySelector, equalityComparer); + } + + Assert.DoesNotThrow(Code); + } + + [Test] + public void BatchByDoNotThrowOnUnknownKeyFromKeySelector() + { + using var source = TestingSequence.Of(0, 1, 2, 3); + static string KeySelector(int i) => $"#{i}#"; + var acceptedKeys = TestingSequence.Of("0", "1", "1", "3"); + var equalityComparer = EqualityComparer.Default; + + void Code() + { + source.BatchBy(acceptedKeys, KeySelector, equalityComparer); + } + + Assert.DoesNotThrow(Code); + } + + [Test] + public void BatchByIsLazy() + { + var source = new BreakingSequence(); + var keySelector = BreakingFunc.Of(); + var acceptedKeys = new BreakingSequence(); + var equalityComparer = EqualityComparer.Default; + + void Code() + { + source.BatchBy(acceptedKeys, keySelector, equalityComparer); + } + + Assert.DoesNotThrow(Code); + } + + [Test] + public void BatchByThrowOnDuplicateAcceptedKeyOnFirstIteration() + { + using var source = TestingSequence.Of(0, 1, 2, 3); + static string KeySelector(int i) => $"{i}"; + var acceptedKeys = TestingSequence.Of("0", "1", "1", "3"); + var equalityComparer = EqualityComparer.Default; + + void Code() + { + source.BatchBy(acceptedKeys, KeySelector, equalityComparer).GetEnumerator().MoveNext(); + } + + Assert.Throws(Code); + } + + [Test] + public void BatchByThrowOnNullAcceptedKeyOnFirstIteration() + { + using var source = TestingSequence.Of(0, 1, 2, 3); + static string KeySelector(int i) => $"{i}"; + var acceptedKeys = TestingSequence.Of("0", "1", null, "3"); + var equalityComparer = EqualityComparer.Default; + + void Code() + { + source.BatchBy(acceptedKeys, KeySelector, equalityComparer).GetEnumerator().MoveNext(); + } + + Assert.Throws(Code); + } + } +} diff --git a/MoreLinq.Test/MoreLinq.Test.csproj b/MoreLinq.Test/MoreLinq.Test.csproj index 1dc81cafe..be62189b3 100644 --- a/MoreLinq.Test/MoreLinq.Test.csproj +++ b/MoreLinq.Test/MoreLinq.Test.csproj @@ -48,6 +48,7 @@ + diff --git a/MoreLinq/BatchBy.cs b/MoreLinq/BatchBy.cs new file mode 100644 index 000000000..0da066248 --- /dev/null +++ b/MoreLinq/BatchBy.cs @@ -0,0 +1,242 @@ +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System.Linq; + +namespace MoreLinq +{ + using System; + using System.Collections.Generic; + + static partial class MoreEnumerable + { + /// + /// Batch the sequence into buckets that are IDictionary. + /// Each buckets contains all keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the returned buckets. + /// Type of elements in sequence. + /// The source sequence. + /// Sequence of accepted keys. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// The sequence is fully consumed on first iteration. + /// If is empty, is not enumerated. + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , or + /// is null + /// contains null + /// contains duplicate keys relatively to + /// . + + public static IEnumerable> BatchBy(this IEnumerable source, + IEnumerable acceptedKeys, + Func keySelector, + IEqualityComparer keyComparer) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); + if (acceptedKeys == null) throw new ArgumentNullException(nameof(acceptedKeys)); + keyComparer ??= EqualityComparer.Default; + + (IList Keys, IDictionary IndexByKey) BuildContext() + { + var keys = acceptedKeys.ToList(); + var indexByKey = new Dictionary(keyComparer); + var index = 0; + foreach (var key in keys) + { + indexByKey.Add(key, index); + index++; + } + + return (keys, indexByKey); + } + var lazyContext = new Lazy<(IList Keys, IDictionary IndexByKey)>(BuildContext); + + return _(); IEnumerable> _() + { + // Lazy creation of the index table and enumeration of acceptedKeys + var (keys, indexByKey) = lazyContext.Value; + foreach (var batch in BatchByImplementation(source, indexByKey, keySelector)) + { + var nextResult = new Dictionary(keys.Count, keyComparer); + for (var i = 0; i < keys.Count; i++) + { + nextResult.Add(keys[i], batch[i]); + } + + yield return nextResult; + } + } + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Each buckets contains all keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the default equality comparer. + /// + /// The type of the keys of the returned buckets. + /// Type of elements in sequence. + /// The source sequence. + /// Sequence of accepted keys. + /// Build the key for elements from the sequence. + /// The build up sequence of buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// The sequence is fully consumed on first iteration. + /// If is empty, is not enumerated. + /// Values from that correspond to a null key are discarded. + /// + /// , or + /// is null + /// contains null + /// contains duplicate keys. + + public static IEnumerable> BatchBy(this IEnumerable source, + IEnumerable acceptedKeys, + Func keySelector) + { + return BatchBy(source, acceptedKeys, keySelector, EqualityComparer.Default); + } + + private static IEnumerable> BatchByImplementation(this IEnumerable source, + IEnumerable acceptedKeys, + Func keySelector, + IEqualityComparer keyComparer) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); + if (acceptedKeys == null) throw new ArgumentNullException(nameof(acceptedKeys)); + keyComparer ??= EqualityComparer.Default; + + IDictionary BuildIndexByKey() + { + var indexByKey = new Dictionary(keyComparer); + var index = 0; + foreach (var key in acceptedKeys) + { + indexByKey.Add(key, index); + index++; + } + + return indexByKey; + } + var lazyIndexByKey = new Lazy>(BuildIndexByKey); + + return _(); IEnumerable> _() + { + // Lazy creation of the index table + var indexByKey = lazyIndexByKey.Value; + foreach (var batch in BatchByImplementation(source, indexByKey, keySelector)) + { + yield return batch; + } + } + } + + private static IEnumerable> BatchByImplementation(IEnumerable source, + IDictionary indexByKey, Func keySelector) + { + var batchSize = indexByKey.Count; + + // acceptedKeys was empty. + if (batchSize == 0) + yield break; + + var queues = new Queue[batchSize]; + for (var i = 0; i < batchSize; i++) + { + queues[i] = new Queue(); + } + + var batch = new TSource[batchSize]; + var takenSlots = new bool[batchSize]; + var emptySlotCount = batchSize; + foreach (var value in source) + { + var key = keySelector(value); + + // reject null key + if (key == null) + continue; + + // reject unknown keys + if (!indexByKey.TryGetValue(key, out var index)) + continue; + + // the slot is already taken, enqueue the value + if (takenSlots[index]) + { + var targetQueue = queues[index]; + targetQueue.Enqueue(value); + continue; + } + + // fill the slot + batch[index] = value; + takenSlots[index] = true; + emptySlotCount--; + + // there are empty slots left, can't yield yet + if (emptySlotCount > 0) + continue; + + // finally can yield a batch + yield return batch; + + // prepare next batch + batch = new TSource[batchSize]; + for (var i = 0; i < batchSize; i++) + { + var queue = queues[i]; + if (queue.Count == 0) + { + takenSlots[i] = false; + emptySlotCount++; + } + else + { + batch[i] = queue.Dequeue(); + takenSlots[i] = true; + } + } + + } + } + } +} diff --git a/MoreLinq/BatchBy.g.cs b/MoreLinq/BatchBy.g.cs new file mode 100644 index 000000000..b337f6312 --- /dev/null +++ b/MoreLinq/BatchBy.g.cs @@ -0,0 +1,1581 @@ +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace MoreLinq +{ + using System; + using System.Collections.Generic; + using System.Linq; + + static partial class MoreEnumerable + { + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + { + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + var keys = new [] + { + firstKey, + secondKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => resultSelector(d[0], d[1])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + Func keySelector, + Func resultSelector) + { + return BatchBy(source, + firstKey, + secondKey, + keySelector, resultSelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + Func keySelector, + IEqualityComparer keyComparer) + { + var keys = new [] + { + firstKey, + secondKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => ValueTuple.Create(d[0], d[1])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + Func keySelector) + { + return BatchBy(source, + firstKey, + secondKey, + keySelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + { + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + var keys = new [] + { + firstKey, + secondKey, + thirdKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => resultSelector(d[0], d[1], d[2])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + Func keySelector, + Func resultSelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + keySelector, resultSelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + Func keySelector, + IEqualityComparer keyComparer) + { + var keys = new [] + { + firstKey, + secondKey, + thirdKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => ValueTuple.Create(d[0], d[1], d[2])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + Func keySelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + keySelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + { + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + var keys = new [] + { + firstKey, + secondKey, + thirdKey, + fourthKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => resultSelector(d[0], d[1], d[2], d[3])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + Func keySelector, + Func resultSelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + fourthKey, + keySelector, resultSelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + Func keySelector, + IEqualityComparer keyComparer) + { + var keys = new [] + { + firstKey, + secondKey, + thirdKey, + fourthKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => ValueTuple.Create(d[0], d[1], d[2], d[3])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + Func keySelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + fourthKey, + keySelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + { + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + var keys = new [] + { + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => resultSelector(d[0], d[1], d[2], d[3], d[4])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + Func keySelector, + Func resultSelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + keySelector, resultSelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + Func keySelector, + IEqualityComparer keyComparer) + { + var keys = new [] + { + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => ValueTuple.Create(d[0], d[1], d[2], d[3], d[4])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + Func keySelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + keySelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + { + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + var keys = new [] + { + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => resultSelector(d[0], d[1], d[2], d[3], d[4], d[5])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + Func keySelector, + Func resultSelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey, + keySelector, resultSelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + Func keySelector, + IEqualityComparer keyComparer) + { + var keys = new [] + { + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => ValueTuple.Create(d[0], d[1], d[2], d[3], d[4], d[5])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + Func keySelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey, + keySelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + { + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + var keys = new [] + { + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey, + seventhKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => resultSelector(d[0], d[1], d[2], d[3], d[4], d[5], d[6])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + Func keySelector, + Func resultSelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey, + seventhKey, + keySelector, resultSelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth, TSource Seventh)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + Func keySelector, + IEqualityComparer keyComparer) + { + var keys = new [] + { + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey, + seventhKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => ValueTuple.Create(d[0], d[1], d[2], d[3], d[4], d[5], d[6])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth, TSource Seventh)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + Func keySelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey, + seventhKey, + keySelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Eighth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + TKey eighthKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + { + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + var keys = new [] + { + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey, + seventhKey, + eighthKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => resultSelector(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Eighth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + TKey eighthKey, + Func keySelector, + Func resultSelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey, + seventhKey, + eighthKey, + keySelector, resultSelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Eighth key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth, TSource Seventh, TSource Eighth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + TKey eighthKey, + Func keySelector, + IEqualityComparer keyComparer) + { + var keys = new [] + { + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey, + seventhKey, + eighthKey + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => ValueTuple.Create(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7])); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Eighth key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth, TSource Seventh, TSource Eighth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + TKey eighthKey, + Func keySelector) + { + return BatchBy(source, + firstKey, + secondKey, + thirdKey, + fourthKey, + fifthKey, + sixthKey, + seventhKey, + eighthKey, + keySelector, null); + } + + } +} diff --git a/MoreLinq/BatchBy.g.tt b/MoreLinq/BatchBy.g.tt new file mode 100644 index 000000000..d8fa00afa --- /dev/null +++ b/MoreLinq/BatchBy.g.tt @@ -0,0 +1,266 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ output extension=".cs" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Collections" #> +<#@ import namespace="System.Globalization" #> +<#@ import namespace="System.Linq" #> +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +<# + var ordinals = new[] + { + string.Empty, + "First", "Second", "Third", "Fourth", + "Fifth", "Sixth", "Seventh", "Eighth" + }; + + var overloads = + from argCount in Enumerable.Range(2, 7) + select new + { + Arguments = + from argPosition in Enumerable.Range(1, argCount) + select new + { + Index = argPosition - 1, + IsFirst = argPosition == 1, + IsLast = argPosition == argCount, + KeyName = ordinals[argPosition].ToLower() + "Key", + Ordinal = ordinals[argPosition], + OutName = ordinals[argPosition] + } + }; +#> +namespace MoreLinq +{ + using System; + using System.Collections.Generic; + using System.Linq; + + static partial class MoreEnumerable + { +<# foreach (var o in overloads) + { +#> + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. +<# foreach (var arg in o.Arguments) { #> + /// <#=arg.Ordinal#> key. +<# } #> + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// <# foreach (var arg in o.Arguments) { #><#=arg.IsLast?",":", "#><# } #> + + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, +<# foreach (var arg in o.Arguments) { #> + TKey <#=arg.KeyName#>, +<# } #> + Func keySelector, + Func<<# foreach (var arg in o.Arguments) { #>TSource, <#}#>TResult> resultSelector, + IEqualityComparer keyComparer) + { + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + var keys = new [] + { +<# foreach (var arg in o.Arguments) { #> + <#=arg.KeyName#><#= arg.IsLast ? "" : "," #> +<# } #> + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => resultSelector(<# foreach (var arg in o.Arguments) { #>d[<#= arg.Index #>]<#= arg.IsLast ? "" : ", " #><# } #> +)); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. +<# foreach (var arg in o.Arguments) { #> + /// <#=arg.Ordinal#> key. +<# } #> + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// <# foreach (var arg in o.Arguments) { #><#=arg.IsLast?",":", "#><# } #> + + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, +<# foreach (var arg in o.Arguments) { #> + TKey <#=arg.KeyName#>, +<# } #> + Func keySelector, + Func<<# foreach (var arg in o.Arguments) { #>TSource, <#}#>TResult> resultSelector) + { + return BatchBy(source, +<# foreach (var arg in o.Arguments) { #> + <#=arg.KeyName#>, +<# } #> + keySelector, resultSelector, null); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. +<# foreach (var arg in o.Arguments) { #> + /// <#=arg.Ordinal#> key. +<# } #> + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// <# foreach (var arg in o.Arguments) { #><#=arg.IsLast?" or":", "#><# } #> + + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(<# foreach (var arg in o.Arguments) { #>TSource <#=arg.OutName#><#=arg.IsLast?"":", "#><#}#>)> + BatchBy( + this IEnumerable source, +<# foreach (var arg in o.Arguments) { #> + TKey <#=arg.KeyName#>, +<# } #> + Func keySelector, + IEqualityComparer keyComparer) + { + var keys = new [] + { +<# foreach (var arg in o.Arguments) { #> + <#=arg.KeyName#><#= arg.IsLast ? "" : "," #> +<# } #> + }; + + return BatchByImplementation(source, keys, keySelector, keyComparer) + .Select(d => ValueTuple.Create(<# foreach (var arg in o.Arguments) { #>d[<#= arg.Index #>]<#= arg.IsLast ? "" : ", " #><# } #> +)); + } + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. +<# foreach (var arg in o.Arguments) { #> + /// <#=arg.Ordinal#> key. +<# } #> + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// <# foreach (var arg in o.Arguments) { #><#=arg.IsLast?" or":", "#><# } #> + + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(<# foreach (var arg in o.Arguments) { #>TSource <#=arg.OutName#><#=arg.IsLast?"":", "#><#}#>)> + BatchBy( + this IEnumerable source, +<# foreach (var arg in o.Arguments) { #> + TKey <#=arg.KeyName#>, +<# } #> + Func keySelector) + { + return BatchBy(source, +<# foreach (var arg in o.Arguments) { #> + <#=arg.KeyName#>, +<# } #> + keySelector, null); + } + +<# } #> + } +} diff --git a/MoreLinq/Extensions.g.cs b/MoreLinq/Extensions.g.cs index 0b1211058..2af0d4bf8 100644 --- a/MoreLinq/Extensions.g.cs +++ b/MoreLinq/Extensions.g.cs @@ -701,6 +701,1344 @@ public static IEnumerable Batch(this IEnumerableBatchBy extension. + + [GeneratedCode("MoreLinq.ExtensionsGenerator", "1.0.0.0")] + public static partial class BatchByExtension + { + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Each buckets contains all keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the default equality comparer. + /// + /// The type of the keys of the returned buckets. + /// Type of elements in sequence. + /// The source sequence. + /// Sequence of accepted keys. + /// Build the key for elements from the sequence. + /// The build up sequence of buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// The sequence is fully consumed on first iteration. + /// If is empty, is not enumerated. + /// Values from that correspond to a null key are discarded. + /// + /// , or + /// is null + /// contains null + /// contains duplicate keys. + + public static IEnumerable> BatchBy(this IEnumerable source, + IEnumerable acceptedKeys, + Func keySelector) + => MoreEnumerable.BatchBy(source, acceptedKeys, keySelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + Func keySelector) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, keySelector); + /// + /// Batch the sequence into buckets that are IDictionary. + /// Each buckets contains all keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the returned buckets. + /// Type of elements in sequence. + /// The source sequence. + /// Sequence of accepted keys. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// The sequence is fully consumed on first iteration. + /// If is empty, is not enumerated. + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , or + /// is null + /// contains null + /// contains duplicate keys relatively to + /// . + + public static IEnumerable> BatchBy(this IEnumerable source, + IEnumerable acceptedKeys, + Func keySelector, + IEqualityComparer keyComparer) + => MoreEnumerable.BatchBy(source, acceptedKeys, keySelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + Func keySelector) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, keySelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + Func keySelector, + IEqualityComparer keyComparer) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, keySelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + Func keySelector) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, keySelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + Func keySelector, + IEqualityComparer keyComparer) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, keySelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + Func keySelector) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, keySelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + Func keySelector, + IEqualityComparer keyComparer) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, keySelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + Func keySelector) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, keySelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + Func keySelector, + IEqualityComparer keyComparer) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, keySelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth, TSource Seventh)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + Func keySelector) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, seventhKey, keySelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + Func keySelector, + IEqualityComparer keyComparer) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, keySelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Eighth key. + /// Build the key for elements from the sequence. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , , , or + /// is null + /// There is some duplicate keys. + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth, TSource Seventh, TSource Eighth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + TKey eighthKey, + Func keySelector) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, seventhKey, eighthKey, keySelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth, TSource Seventh)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + Func keySelector, + IEqualityComparer keyComparer) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, seventhKey, keySelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values returned as ValueTuple. + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Eighth key. + /// Build the key for elements from the sequence. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , , , or + /// is null + /// There is some duplicate keys relatively to + + public static IEnumerable<(TSource First, TSource Second, TSource Third, TSource Fourth, TSource Fifth, TSource Sixth, TSource Seventh, TSource Eighth)> + BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + TKey eighthKey, + Func keySelector, + IEqualityComparer keyComparer) + => MoreEnumerable. BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, seventhKey, eighthKey, keySelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + Func keySelector, + Func resultSelector) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, keySelector, resultSelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + Func keySelector, + Func resultSelector) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, keySelector, resultSelector); + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, keySelector, resultSelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + Func keySelector, + Func resultSelector) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, keySelector, resultSelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, keySelector, resultSelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + Func keySelector, + Func resultSelector) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, keySelector, resultSelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, keySelector, resultSelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + Func keySelector, + Func resultSelector) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, keySelector, resultSelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, keySelector, resultSelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + Func keySelector, + Func resultSelector) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, seventhKey, keySelector, resultSelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, keySelector, resultSelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals. + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Eighth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// + /// , + /// , , , , , , , , + /// or is null + /// There is some duplicate keys. + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + TKey eighthKey, + Func keySelector, + Func resultSelector) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, seventhKey, eighthKey, keySelector, resultSelector); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, seventhKey, keySelector, resultSelector, keyComparer); + + /// + /// Batch the sequence into buckets that are IDictionary. + /// Then the buckets values are projected with . + /// Each buckets contains all of the given keys and for each of this + /// keys a matching value from the sequence. + /// The matching is done by the . + /// + /// Values from sequence that doesn't have a matching key are discarded. + /// + /// For each key/value pair in a buckets, key and keySelector(value) are equals + /// relatively to the . + /// + /// The type of the keys of the buckets. + /// Type of elements in sequence. + /// Type of the projected value. + /// The source sequence. + /// First key. + /// Second key. + /// Third key. + /// Fourth key. + /// Fifth key. + /// Sixth key. + /// Seventh key. + /// Eighth key. + /// Build the key for elements from the sequence. + /// The function used to project the buckets. + /// The comparer used to evaluate keys equality. + /// The build up sequence of projected buckets. + /// + /// This operator uses deferred execution and streams its results. + /// + /// Values from that correspond to a null key are discarded. + /// If is null, EqualityComparer.Default is used. + /// + /// , + /// , , , , , , , , + /// or is null + /// There is some duplicate keys relatively to . + + public static IEnumerable BatchBy( + this IEnumerable source, + TKey firstKey, + TKey secondKey, + TKey thirdKey, + TKey fourthKey, + TKey fifthKey, + TKey sixthKey, + TKey seventhKey, + TKey eighthKey, + Func keySelector, + Func resultSelector, + IEqualityComparer keyComparer) + => MoreEnumerable.BatchBy(source, firstKey, secondKey, thirdKey, fourthKey, fifthKey, sixthKey, seventhKey, eighthKey, keySelector, resultSelector, keyComparer); + + } + /// Cartesian extension. [GeneratedCode("MoreLinq.ExtensionsGenerator", "1.0.0.0")] diff --git a/MoreLinq/MoreLinq.csproj b/MoreLinq/MoreLinq.csproj index dbe55aa50..6824a8660 100644 --- a/MoreLinq/MoreLinq.csproj +++ b/MoreLinq/MoreLinq.csproj @@ -156,6 +156,10 @@ TextTemplatingFileGenerator Aggregate.g.cs + + TextTemplatingFileGenerator + BatchBy.g.cs + TextTemplatingFileGenerator Cartesian.g.cs @@ -208,6 +212,11 @@ True Aggregate.g.tt + + True + True + BatchBy.g.tt + True True diff --git a/README.md b/README.md index 29661bedf..ac881c823 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,14 @@ Batches the source sequence into sized buckets. This method has 2 overloads. +### BatchBy + +Batch by key the source sequence into buckets that are dictionary. +Each buckets contains all accepted keys and for each of this +keys a matching value from the source sequence. + +This method has 30 overloads. + ### Cartesian Returns the Cartesian product of two or more sequences by combining each