From e511b35ad404d59aa0a5468c5993287a85a46e92 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 17 Aug 2023 10:09:38 -0600 Subject: [PATCH 001/124] Add linqpad samples to nuget package --- Source/SuperLinq/SuperLinq.csproj | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/SuperLinq/SuperLinq.csproj b/Source/SuperLinq/SuperLinq.csproj index 81ee7849..9d1dee49 100644 --- a/Source/SuperLinq/SuperLinq.csproj +++ b/Source/SuperLinq/SuperLinq.csproj @@ -11,7 +11,7 @@ SuperLinq SuperLinq Developers - linq;extensions + linq;extensions;linqpad-samples Apache-2.0 readme.md @@ -141,8 +141,14 @@ $([System.Text.RegularExpressions.Regex]::Replace($(Copyright), `\s+`, ` `).Trim()) - + + + + + From c05d4130f483c4378641d2f77b8a2ed8e480aa65 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 4 Aug 2023 20:17:28 -0500 Subject: [PATCH 002/124] Update documentation for `AggregateRight` --- ...uperLinq.SuperEnumerable.AggregateRight.md | 18 +++ .../AggregateRight/AggregateRight1.linq | 15 ++ .../AggregateRight/AggregateRight2.linq | 15 ++ .../AggregateRight/AggregateRight3.linq | 18 +++ Source/SuperLinq/AggregateRight.cs | 141 ++++++++++-------- 5 files changed, 145 insertions(+), 62 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AggregateRight.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AggregateRight.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AggregateRight.md new file mode 100644 index 00000000..e2c8afd9 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AggregateRight.md @@ -0,0 +1,18 @@ +--- +uid: SuperLinq.SuperEnumerable.AggregateRight``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0}) +example: [*content] +--- +The following code example demonstrates how to collect numbers into a string using `AggregateRight`. +[!code-csharp[](SuperLinq/AggregateRight/AggregateRight1.linq#L6-)] +--- +uid: SuperLinq.SuperEnumerable.AggregateRight``2(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``0,``1,``1}) +example: [*content] +--- +The following code example demonstrates how to collect numbers into a string using `AggregateRight`. +[!code-csharp[](SuperLinq/AggregateRight/AggregateRight2.linq#L6-)] +--- +uid: SuperLinq.SuperEnumerable.AggregateRight``3(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``0,``1,``1},System.Func{``1,``2}) +example: [*content] +--- +The following code example demonstrates how to collect numbers into a string using `AggregateRight`. +[!code-csharp[](SuperLinq/AggregateRight/AggregateRight3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight1.linq new file mode 100644 index 00000000..c78c98b6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight1.linq @@ -0,0 +1,15 @@ + + SuperLinq + SuperLinq + + +var numbers = new string[] { "1", "2", "3", "4", "5", }; + +// Enumerate strings from right to left and collect the text into larger strings. +var result = numbers + .AggregateRight((a, b) => $"({a}/{b})"); + +Console.WriteLine(result); + +// This code produces the following output: +// (1/(2/(3/(4/5)))) diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight2.linq new file mode 100644 index 00000000..0fed4aa2 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight2.linq @@ -0,0 +1,15 @@ + + SuperLinq + SuperLinq + + +var numbers = new string[] { "1", "2", "3", "4", "5", }; + +// Enumerate strings from right to left and collect the text into larger strings. +var result = numbers + .AggregateRight("6", (a, b) => $"({a}/{b})"); + +Console.WriteLine(result); + +// This code produces the following output: +// (1/(2/(3/(4/(5/6))))) diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight3.linq new file mode 100644 index 00000000..93123483 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight3.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var numbers = new string[] { "1", "2", "3", "4", "5", }; + +// Enumerate strings from right to left and collect the text into larger strings. +var result = numbers + .AggregateRight( + "6", + (a, b) => $"({a}/{b})", + s => s.Length); + +Console.WriteLine(result); + +// This code produces the following output: +// 21 diff --git a/Source/SuperLinq/AggregateRight.cs b/Source/SuperLinq/AggregateRight.cs index 0c88ef0b..cf1acfe3 100644 --- a/Source/SuperLinq/AggregateRight.cs +++ b/Source/SuperLinq/AggregateRight.cs @@ -3,24 +3,27 @@ public static partial class SuperEnumerable { /// - /// Applies a right-associative accumulator function over a sequence. - /// This operator is the right-associative version of the - /// LINQ operator. + /// Applies a right-associative accumulator function over a sequence. This operator is the right-associative + /// version of the LINQ operator. /// - /// The type of the elements of source. - /// Source sequence. - /// A right-associative accumulator function to be invoked on each element. - /// The final accumulator value. - /// is . - /// is . - /// - /// i.ToString()).AggregateRight((a, b) => string.Format("({0}/{1})", a, b)); - /// ]]> - /// The result variable will contain "(1/(2/(3/(4/5))))". - /// + /// + /// The type of the elements of source. + /// + /// + /// Source sequence. + /// + /// + /// A right-associative accumulator function to be invoked on each element. + /// + /// + /// The final accumulator value. + /// + /// + /// or is . + /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// public static TSource AggregateRight(this IEnumerable source, Func func) { @@ -41,30 +44,35 @@ public static TSource AggregateRight(this IEnumerable source, } /// - /// Applies a right-associative accumulator function over a sequence. - /// The specified seed value is used as the initial accumulator value. - /// This operator is the right-associative version of the - /// LINQ operator. + /// Applies a right-associative accumulator function over a sequence. The specified + /// value is used as the initial accumulator value. This operator is the right-associative version of the LINQ operator. /// - /// The type of the elements of source. - /// The type of the accumulator value. - /// Source sequence. - /// The initial accumulator value. - /// A right-associative accumulator function to be invoked on each element. - /// The final accumulator value. - /// is . - /// is . - /// - /// string.Format("({0}/{1})", a, b)); - /// ]]> - /// The result variable will contain "(1/(2/(3/(4/(5/6)))))". - /// + /// + /// The type of the elements of source. + /// + /// + /// The type of the accumulator value. + /// + /// + /// Source sequence. + /// + /// + /// The initial accumulator value. + /// + /// + /// A right-associative accumulator function to be invoked on each element. + /// + /// + /// The final accumulator value. + /// + /// + /// or is . + /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// - public static TAccumulate AggregateRight(this IEnumerable source, TAccumulate seed, Func func) { Guard.IsNotNull(source); @@ -79,34 +87,43 @@ public static TAccumulate AggregateRight(this IEnumerable< } /// - /// Applies a right-associative accumulator function over a sequence. - /// The specified seed value is used as the initial accumulator value, - /// and the specified function is used to select the result value. - /// This operator is the right-associative version of the - /// LINQ operator. + /// Applies a right-associative accumulator function over a sequence. The specified + /// value is used as the initial accumulator value, and the function is used + /// to select the result value. This operator is the right-associative version of the LINQ operator. /// - /// The type of the elements of source. - /// The type of the accumulator value. - /// The type of the resulting value. - /// Source sequence. - /// The initial accumulator value. - /// A right-associative accumulator function to be invoked on each element. - /// A function to transform the final accumulator value into the result value. - /// The transformed final accumulator value. - /// is . - /// is . - /// is . - /// - /// string.Format("({0}/{1})", a, b), str => str.Length); - /// ]]> - /// The result variable will contain 21. - /// + /// + /// The type of the elements of source. + /// + /// + /// The type of the accumulator value. + /// + /// + /// The type of the resulting value. + /// + /// + /// Source sequence. + /// + /// + /// The initial accumulator value. + /// + /// + /// A right-associative accumulator function to be invoked on each element. + /// + /// + /// A function to transform the final accumulator value into the result value. + /// + /// + /// The transformed final accumulator value. + /// + /// + /// , , or is . + /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// - public static TResult AggregateRight(this IEnumerable source, TAccumulate seed, Func func, Func resultSelector) { Guard.IsNotNull(source); From 306ca056e5d98d0602635128c0680a77b5d21e5e Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 4 Aug 2023 20:17:41 -0500 Subject: [PATCH 003/124] Update documentation for `AssertCount` --- .../SuperLinq.SuperEnumerable.AssertCount.md | 6 ++++ .../SuperLinq/AssertCount/AssertCount.linq | 28 ++++++++++++++++ Source/SuperLinq/AssertCount.cs | 33 ++++++++++++------- 3 files changed, 56 insertions(+), 11 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AssertCount.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/AssertCount/AssertCount.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AssertCount.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AssertCount.md new file mode 100644 index 00000000..c17d7500 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AssertCount.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.AssertCount``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to validate the length of a sequence using `AssertCount`. +[!code-csharp[](SuperLinq/AssertCount/AssertCount.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AssertCount/AssertCount.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AssertCount/AssertCount.linq new file mode 100644 index 00000000..03b5bfc3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AssertCount/AssertCount.linq @@ -0,0 +1,28 @@ + + SuperLinq + SuperLinq + + +var numbers = new string[] { "1", "2", "3", "4", "5", }; + +// Enumerate the sequence with a valid length. +// This code executes normally. +numbers + .AssertCount(5) + .Consume(); + +// Enumerate the sequence with an invalid length. +// This code throws an `ArgumentException` +try +{ + numbers + .AssertCount(4) + .Consume(); +} +catch (ArgumentException ae) +{ + Console.WriteLine(ae.Message); + + // This code produces the following output: + // Parameter "source.Count()" (int) must be equal to <4>, was <5>. (Parameter 'source.Count()') +} \ No newline at end of file diff --git a/Source/SuperLinq/AssertCount.cs b/Source/SuperLinq/AssertCount.cs index 7a89c7f9..75b9194e 100644 --- a/Source/SuperLinq/AssertCount.cs +++ b/Source/SuperLinq/AssertCount.cs @@ -3,21 +3,32 @@ public static partial class SuperEnumerable { /// - /// Asserts that a source sequence contains a given count of elements. + /// Asserts that a source sequence contains a given count of elements. /// - /// Type of elements in sequence. - /// Source sequence. - /// Count to assert. + /// + /// Type of elements in sequence. + /// + /// + /// Source sequence. + /// + /// + /// Count to assert. + /// /// - /// Returns the original sequence as long it is contains the number of elements specified by . Otherwise it throws . + /// Returns the original sequence as long it is contains the number of elements specified by . Otherwise it throws . /// - /// is null. - /// is less than 0. - /// has a length different than . + /// + /// is . + /// + /// + /// is less than 0. + /// + /// + /// Thrown lazily has a length different than . + /// /// - /// This operator uses deferred execution and streams its results. + /// The sequence length is evaluated lazily during the enumeration of the sequence. /// public static IEnumerable AssertCount(this IEnumerable source, int count) { From 6af45a0c6c2d3027ce3d69f98bbfd418837867d5 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 5 Aug 2023 08:41:04 -0500 Subject: [PATCH 004/124] Update documentation for `Backsert` --- .../SuperLinq.SuperEnumerable.Backsert.md | 9 ++++ .../apidoc/SuperLinq/Backsert/Backsert.linq | 16 +++++++ Source/SuperLinq/Backsert.cs | 44 ++++++++++--------- 3 files changed, 49 insertions(+), 20 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Backsert.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Backsert/Backsert.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Backsert.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Backsert.md new file mode 100644 index 00000000..f2149dec --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Backsert.md @@ -0,0 +1,9 @@ +--- +uid: SuperLinq.SuperEnumerable.Backsert``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +> [!NOTE] +> `Backsert` has been deprecated in favor of `Insert`. Please see [here](xref:SuperLinq.SuperEnumerable.Insert``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0},System.Index)) for documentation on the equivalent method. + +The following code example demonstrates how to insert one sequence into another, using `Backsert`. +[!code-csharp[](SuperLinq/Backsert/Backsert.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Backsert/Backsert.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Backsert/Backsert.linq new file mode 100644 index 00000000..ed3ec49a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Backsert/Backsert.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var first = Enumerable.Range(1, 5); +var second = Enumerable.Range(1, 5); + +// Insert one sequence into another +var result = first + .Backsert(second, 2); + +Console.WriteLine(string.Join(", ", result)); + +// This code produces the following output: +// 1, 2, 3, 1, 2, 3, 4, 5, 4, 5 diff --git a/Source/SuperLinq/Backsert.cs b/Source/SuperLinq/Backsert.cs index e9c61a06..d98969ac 100644 --- a/Source/SuperLinq/Backsert.cs +++ b/Source/SuperLinq/Backsert.cs @@ -3,36 +3,40 @@ public static partial class SuperEnumerable { /// - /// Inserts the elements of a sequence into another sequence at a - /// specified index from the tail of the sequence, where zero always - /// represents the last position, one represents the second-last - /// element, two represents the third-last element and so on. + /// Inserts the elements of a sequence into another sequence at a specified index from the tail of the sequence, + /// where zero always represents the last position, one represents the second-last element, two represents the + /// third-last element and so on. /// /// - /// Type of elements in all sequences. - /// The source sequence. - /// The sequence that will be inserted. + /// Type of elements in all sequences. + /// + /// + /// The source sequence. + /// + /// + /// The sequence that will be inserted. + /// /// - /// The zero-based index from the end of where - /// elements from should be inserted. - /// . + /// The zero-based index from the end of where elements from + /// should be inserted. . + /// /// - /// A sequence that contains the elements of - /// plus the elements of inserted at - /// the given index from the end of . + /// A sequence that contains the elements of plus the elements of inserted at the given index from the end of . /// - /// is . - /// is . + /// + /// or is . + /// /// - /// Thrown if is negative. + /// is negative. /// /// - /// Thrown lazily if is greater than the - /// length of . The validation occurs when - /// the resulting sequence is iterated. + /// Thrown lazily if is greater than the length of . /// /// - /// This method uses deferred execution and streams its results. + /// + /// This operator uses deferred execution and streams its results. + /// /// [Obsolete("Backsert has been replaced by Insert(second, Index index)")] public static IEnumerable Backsert(this IEnumerable first, IEnumerable second, int index) From ce106314659664d61ea50626eae36bb5fe0fd69f Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 18 Aug 2023 08:12:47 -0600 Subject: [PATCH 005/124] Update documentation for `Aggregate` --- .../SuperLinq.SuperEnumerable.Aggregate.md | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Aggregate.md diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Aggregate.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Aggregate.md new file mode 100644 index 00000000..2ae38161 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Aggregate.md @@ -0,0 +1,98 @@ +--- +uid: SuperLinq.SuperEnumerable.Aggregate``10(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3},``4,System.Func{``4,``0,``4},``5,System.Func{``5,``0,``5},``6,System.Func{``6,``0,``6},``7,System.Func{``7,``0,``7},``8,System.Func{``8,``0,``8},System.Func{``1,``2,``3,``4,``5,``6,``7,``8,``9}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and passes the final values to resultSelector. +--- +uid: SuperLinq.SuperEnumerable.Aggregate``3(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and returns the final values in a +--- +uid: SuperLinq.SuperEnumerable.Aggregate``4(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},System.Func{``1,``2,``3}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and passes the final values to resultSelector. +--- +uid: SuperLinq.SuperEnumerable.Aggregate``4(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and returns the final values in a +--- +uid: SuperLinq.SuperEnumerable.Aggregate``5(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3},System.Func{``1,``2,``3,``4}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and passes the final values to resultSelector. +--- +uid: SuperLinq.SuperEnumerable.Aggregate``5(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3},``4,System.Func{``4,``0,``4}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and returns the final values in a +--- +uid: SuperLinq.SuperEnumerable.Aggregate``6(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3},``4,System.Func{``4,``0,``4},System.Func{``1,``2,``3,``4,``5}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and passes the final values to resultSelector. +--- +uid: SuperLinq.SuperEnumerable.Aggregate``6(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3},``4,System.Func{``4,``0,``4},``5,System.Func{``5,``0,``5}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and returns the final values in a +--- +uid: SuperLinq.SuperEnumerable.Aggregate``7(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3},``4,System.Func{``4,``0,``4},``5,System.Func{``5,``0,``5},System.Func{``1,``2,``3,``4,``5,``6}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and passes the final values to resultSelector. +--- +uid: SuperLinq.SuperEnumerable.Aggregate``7(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3},``4,System.Func{``4,``0,``4},``5,System.Func{``5,``0,``5},``6,System.Func{``6,``0,``6}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and returns the final values in a +--- +uid: SuperLinq.SuperEnumerable.Aggregate``8(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3},``4,System.Func{``4,``0,``4},``5,System.Func{``5,``0,``5},``6,System.Func{``6,``0,``6},System.Func{``1,``2,``3,``4,``5,``6,``7}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and passes the final values to resultSelector. +--- +uid: SuperLinq.SuperEnumerable.Aggregate``8(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3},``4,System.Func{``4,``0,``4},``5,System.Func{``5,``0,``5},``6,System.Func{``6,``0,``6},``7,System.Func{``7,``0,``7}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and returns the final values in a +--- +uid: SuperLinq.SuperEnumerable.Aggregate``9(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3},``4,System.Func{``4,``0,``4},``5,System.Func{``5,``0,``5},``6,System.Func{``6,``0,``6},``7,System.Func{``7,``0,``7},System.Func{``1,``2,``3,``4,``5,``6,``7,``8}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and passes the final values to resultSelector. +--- +uid: SuperLinq.SuperEnumerable.Aggregate``9(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1},``2,System.Func{``2,``0,``2},``3,System.Func{``3,``0,``3},``4,System.Func{``4,``0,``4},``5,System.Func{``5,``0,``5},``6,System.Func{``6,``0,``6},``7,System.Func{``7,``0,``7},``8,System.Func{``8,``0,``8}) +example: [*content] +--- +For an example using a single seed and aggregate, please see . + +This operator uses multiple seeds and aggregates and returns the final values in a From f34fe931ac5d51eb6a5f2a1c1e91d6e2b6168f3f Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 18 Aug 2023 08:35:11 -0600 Subject: [PATCH 006/124] Update documentation for `Batch` --- .../apidoc/SuperLinq.SuperEnumerable.Batch.md | 24 ++++ .../apidoc/SuperLinq/Batch/Batch1.linq | 19 +++ .../apidoc/SuperLinq/Batch/Batch2.linq | 20 +++ .../apidoc/SuperLinq/Batch/Batch3.linq | 21 +++ .../apidoc/SuperLinq/Batch/Batch4.linq | 22 +++ Source/SuperLinq/Batch.Buffered.cs | 135 ++++++++++++------ Source/SuperLinq/Batch.cs | 38 +++-- 7 files changed, 222 insertions(+), 57 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Batch.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Batch.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Batch.md new file mode 100644 index 00000000..43538f00 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Batch.md @@ -0,0 +1,24 @@ +--- +uid: SuperLinq.SuperEnumerable.Batch``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to break a sequence into chunks of a specific size, using `Batch`. +[!code-csharp[](SuperLinq/Batch/Batch1.linq#L6-)] +--- +uid: SuperLinq.SuperEnumerable.Batch``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to break a sequence into chunks of a specific size, using `Batch`. +[!code-csharp[](SuperLinq/Batch/Batch2.linq#L6-)] +--- +uid: SuperLinq.SuperEnumerable.Batch``2(System.Collections.Generic.IEnumerable{``0},``0[],System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to break a sequence into chunks of a specific size, using `Batch`. +[!code-csharp[](SuperLinq/Batch/Batch3.linq#L6-)] +--- +uid: SuperLinq.SuperEnumerable.Batch``2(System.Collections.Generic.IEnumerable{``0},``0[],System.Int32,System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to break a sequence into chunks of a specific size, using `Batch`. +[!code-csharp[](SuperLinq/Batch/Batch4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch1.linq new file mode 100644 index 00000000..e421cba0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch1.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Break the sequence of numbers into three chunks of 3 and one chunk of 1 +var result = sequence.Batch(3); + +Console.WriteLine( + "[" + + string.Join( + ", ", + result.Select(c => "[" + string.Join(", ", c) + "]")) + + "]"); + +// This code produces the following output: +// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch2.linq new file mode 100644 index 00000000..ec1a4dec --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch2.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Break the sequence of numbers into three chunks of 3 and one chunk of 1 +var result = sequence + .Batch( + 3, + c => "[" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch3.linq new file mode 100644 index 00000000..b0d931d1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch3.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Break the sequence of numbers into three chunks of 3 and one chunk of 1 +var buffer = new int[3]; +var result = sequence + .Batch( + buffer, + c => "[" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch4.linq new file mode 100644 index 00000000..4af1780c --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch4.linq @@ -0,0 +1,22 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Break the sequence of numbers into three chunks of 3 and one chunk of 1 +var buffer = new int[5]; +var result = sequence + .Batch( + buffer, + 3, + c => "[" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]] diff --git a/Source/SuperLinq/Batch.Buffered.cs b/Source/SuperLinq/Batch.Buffered.cs index 515d9333..fd16e891 100644 --- a/Source/SuperLinq/Batch.Buffered.cs +++ b/Source/SuperLinq/Batch.Buffered.cs @@ -3,28 +3,43 @@ public static partial class SuperEnumerable { /// - /// Split the elements of a sequence into chunks of size at most . + /// Split the elements of a sequence into chunks of size at most . /// - /// The type of the elements of . - /// The type of the value return by . - /// An whose elements to chunk. - /// The maximum size of each chunk. - /// A transform function to apply to each chunk. - /// A sequence of elements returned by . - /// or is - /// null. - /// is below 1. + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// An whose elements to chunk. + /// + /// + /// The maximum size of each chunk. + /// + /// + /// A transform function to apply to each chunk. + /// + /// + /// A sequence of elements returned by . + /// + /// + /// or is . + /// + /// + /// is below 1. + /// /// /// - /// A chunk can contain fewer elements than , specifically the final chunk of . + /// A chunk can contain fewer elements than , specifically the final chunk of . /// /// - /// In this overload of Batch, a single array of length is allocated as a buffer for - /// all subsequences. + /// In this overload of Batch, a single array of length is allocated as a buffer + /// for all subsequences. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// /// public static IEnumerable Batch( @@ -40,26 +55,40 @@ public static IEnumerable Batch( } /// - /// Split the elements of a sequence into chunks of size at most .Length. + /// Split the elements of a sequence into chunks of size at most .Length. /// - /// The type of the elements of . - /// The type of the value return by . - /// An whose elements to chunk. - /// An array to use as a buffer for each chunk. - /// A transform function to apply to each chunk. - /// A sequence of elements returned by . - /// , , or - /// is null. + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// An whose elements to chunk. + /// + /// + /// The array to use as a buffer for each chunk + /// + /// + /// A transform function to apply to each chunk. + /// + /// + /// A sequence of elements returned by . + /// + /// + /// , , or is . + /// /// /// - /// A chunk can contain fewer elements than .Length, specifically the final chunk of - /// . + /// A chunk can contain fewer elements than .Length, specifically the final chunk + /// of . /// /// - /// In this overload of Batch, is used as a common buffer for all subsequences. + /// In this overload of Batch, is used as a common buffer for all subsequences. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// /// public static IEnumerable Batch( @@ -75,31 +104,45 @@ public static IEnumerable Batch( } /// - /// Split the elements of a sequence into chunks of size at most . + /// Split the elements of a sequence into chunks of size at most . /// - /// The type of the elements of . - /// The type of the value return by . - /// An whose elements to chunk. - /// The maximum size of each chunk. - /// An array to use as a buffer for each chunk. - /// A transform function to apply to each chunk. - /// A sequence of elements returned by . - /// , , or - /// is null. - /// is below 1 or above .Length. + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// An whose elements to chunk. + /// + /// + /// The array to use as a buffer for each chunk + /// + /// + /// The maximum size of each chunk. + /// + /// + /// A transform function to apply to each chunk. + /// + /// + /// A sequence of elements returned by . + /// + /// + /// , , or is . + /// /// /// - /// A chunk can contain fewer elements than , specifically the final chunk of . + /// A chunk can contain fewer elements than , specifically the final chunk of . /// /// - /// In this overload of Batch, is used as a common buffer for all subsequences.
- /// This overload is provided to ease usage of common buffers, such as those rented from , which may return an array larger than requested. + /// In this overload of Batch, is used as a common buffer for all + /// subsequences. This overload is provided to ease usage of common buffers, such as those rented from , which may return an array larger than requested. ///
/// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// ///
public static IEnumerable Batch( diff --git a/Source/SuperLinq/Batch.cs b/Source/SuperLinq/Batch.cs index 49e0980d..c50da55b 100644 --- a/Source/SuperLinq/Batch.cs +++ b/Source/SuperLinq/Batch.cs @@ -3,22 +3,38 @@ public static partial class SuperEnumerable { /// - /// Split the elements of a sequence into chunks of size at most . + /// Split the elements of a sequence into chunks of size at most . /// - /// The type of the elements of . - /// An whose elements to chunk. - /// The maximum size of each chunk. - /// An that contains the elements the input sequence split into chunks of size - /// size. - /// is . - /// is below 1. + /// + /// The type of the elements of . + /// + /// + /// An whose elements to chunk. + /// + /// + /// The maximum size of each chunk. + /// + /// + /// An that contains the elements the input sequence split into chunks of size + /// size. + /// + /// + /// is . + /// + /// + /// is below 1. + /// /// /// - /// A chunk can contain fewer elements than , specifically the final buffer of . + /// A chunk can contain fewer elements than , specifically the final buffer of . /// /// - /// Returned subsequences are buffered, but the overall operation is streamed.
+ /// A separate array is allocated for each returned chunk. Other overloads of Batch are available which + /// do not require additional array allocations for each chunk. + ///
+ /// + /// Returned subsequences are buffered, but the overall operation is streamed.
///
///
public static IEnumerable> Batch(this IEnumerable source, int size) From 0e854c327bbc099cc368e1aba7cc63a52fe86dd2 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 18 Aug 2023 09:22:44 -0600 Subject: [PATCH 007/124] Update documentation for `BindByIndex` --- .../SuperLinq.SuperEnumerable.BindByIndex.md | 14 ++++ .../SuperLinq/BindByIndex/BindByIndex1.linq | 19 +++++ .../SuperLinq/BindByIndex/BindByIndex2.linq | 22 +++++ Source/SuperLinq/BindByIndex.cs | 84 ++++++++++++------- 4 files changed, 111 insertions(+), 28 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.BindByIndex.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.BindByIndex.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.BindByIndex.md new file mode 100644 index 00000000..33dca407 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.BindByIndex.md @@ -0,0 +1,14 @@ +--- +uid: SuperLinq.SuperEnumerable.BindByIndex``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{System.Int32}) +example: [*content] +--- +The following code example demonstrates how to select elements from a sequence by index, using `BindByIndex`. +[!code-csharp[](SuperLinq/BindByIndex/BindByIndex1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.BindByIndex``2(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{System.Int32},System.Func{``0,System.Int32,``1},System.Func{System.Int32,``1}) +example: [*content] +--- +The following code example demonstrates how to select elements from a sequence by index, using `BindByIndex`. +[!code-csharp[](SuperLinq/BindByIndex/BindByIndex2.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex1.linq new file mode 100644 index 00000000..80425e0b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex1.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); +var indices = new int[] { 0, 1, 8, 9, 3, 4, 2, }; + +// Select elements from sequence using the values in indices +var result = sequence + .BindByIndex(indices); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 9, 10, 4, 5, 3] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex2.linq new file mode 100644 index 00000000..e8e477fd --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex2.linq @@ -0,0 +1,22 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); +var indices = new int[] { 0, 1, 8, 10, 3, 4, 2, }; + +// Select elements from sequence using the values in indices +var result = sequence + .BindByIndex( + indices, + (e, i) => e.ToString(), + i => "null"); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 9, null, 4, 5, 3] diff --git a/Source/SuperLinq/BindByIndex.cs b/Source/SuperLinq/BindByIndex.cs index 944a9df2..96181396 100644 --- a/Source/SuperLinq/BindByIndex.cs +++ b/Source/SuperLinq/BindByIndex.cs @@ -3,48 +3,76 @@ public static partial class SuperEnumerable { /// - /// Selects elements by index from a sequence. + /// Selects elements by index from a sequence. /// - /// The type of the elements of . - /// The source sequence. - /// The list of indices of elements in the sequence to select. + /// + /// The type of the elements of . + /// + /// + /// The source sequence. + /// + /// + /// The list of indices of elements in the sequence to select. + /// /// - /// An whose elements are the result of selecting elements according to the sequence. + /// An whose elements are the result of selecting elements according to the + /// sequence. /// - /// is . - /// is . - /// An index in is out of range for the input sequence . + /// + /// or is . + /// + /// + /// (Thrown lazily) An index in is out of range for the input sequence . + /// + /// + /// + /// This operator uses deferred execution and streams its results. + /// + /// public static IEnumerable BindByIndex( this IEnumerable source, IEnumerable indices) { -#pragma warning disable MA0015 return BindByIndex(source, indices, static (e, i) => e, static i => throw new ArgumentOutOfRangeException(nameof(indices), "Index is greater than the length of the first sequence.")); -#pragma warning restore MA0015 } /// - /// Selects elements by index from a sequence and transforms them using the provided functions. + /// Selects elements by index from a sequence and transforms them using the provided functions. /// - /// The type of the elements of . - /// The type of the elements of the resulting sequence. - /// The source sequence. - /// The list of indices of elements in the sequence to select. - /// A transform function to apply to each source element; the second parameter of the function represents the index of the output sequence. - /// A transform function to apply to missing source elements; the parameter represents the index of the output sequence. + /// + /// The type of the elements of . + /// + /// + /// The type of the elements of the resulting sequence. + /// + /// + /// The source sequence. + /// + /// + /// The list of indices of elements in the sequence to select. + /// + /// + /// A transform function to apply to each source element; the second parameter of the function represents the + /// index of the output sequence. + /// + /// + /// A transform function to apply to missing source elements; the parameter represents the index of the output + /// sequence. + /// /// - /// An whose elements are the result of selecting elements according to the sequence - /// and invoking the transform function. + /// An whose elements are the result of selecting elements according to the + /// sequence and invoking the transform function. /// - /// is . - /// is . - /// is . - /// is . - /// - /// - /// This method uses deferred execution and streams its results. - /// - /// + /// + /// , , , or is . + /// + /// + /// + /// This operator uses deferred execution and streams its results. + /// + /// public static IEnumerable BindByIndex( this IEnumerable source, IEnumerable indices, From 0b6aae42fb15ad3aba31a8d574f42e9d92d3297d Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 18 Aug 2023 14:26:04 -0600 Subject: [PATCH 008/124] Update documentation for `Buffer` --- .../SuperLinq.SuperEnumerable.Buffer.md | 13 ++++ .../apidoc/SuperLinq/Buffer/Buffer1.linq | 19 +++++ .../apidoc/SuperLinq/Buffer/Buffer2.linq | 19 +++++ Source/SuperLinq/Buffer.cs | 72 ++++++++++++------- 4 files changed, 99 insertions(+), 24 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Buffer.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Buffer.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Buffer.md new file mode 100644 index 00000000..c8ad1cb2 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Buffer.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.Buffer``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to buffer a sequence using `Buffer`. +[!code-csharp[](SuperLinq/Buffer/Buffer1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Buffer``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Int32) +example: [*content] +--- +The following code example demonstrates how to buffer a sequence using `Buffer`. +[!code-csharp[](SuperLinq/Buffer/Buffer2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer1.linq new file mode 100644 index 00000000..130c72f2 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer1.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Break the sequence of numbers into three chunks of 3 and one chunk of 1 +var result = sequence.Buffer(3); + +Console.WriteLine( + "[" + + string.Join( + ", ", + result.Select(c => "[" + string.Join(", ", c) + "]")) + + "]"); + +// This code produces the following output: +// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer2.linq new file mode 100644 index 00000000..b408ae63 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer2.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Break the sequence of numbers into overlapping chunks of size 3 +var result = sequence.Buffer(3, 2); + +Console.WriteLine( + "[" + + string.Join( + ", ", + result.Select(c => "[" + string.Join(", ", c) + "]")) + + "]"); + +// This code produces the following output: +// [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]] diff --git a/Source/SuperLinq/Buffer.cs b/Source/SuperLinq/Buffer.cs index 3083b28e..4344162b 100644 --- a/Source/SuperLinq/Buffer.cs +++ b/Source/SuperLinq/Buffer.cs @@ -6,25 +6,36 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Generates a sequence of non-overlapping adjacent buffers over the source sequence. + /// Generates a sequence of non-overlapping adjacent buffers over the source sequence. /// - /// Source sequence element type. - /// Source sequence. - /// Number of elements for allocated buffers. - /// Sequence of buffers containing source sequence elements. - /// is . - /// is less than or equal to - /// 0. + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Number of elements for allocated buffers. + /// + /// + /// Sequence of buffers containing source sequence elements. + /// + /// + /// is . + /// + /// + /// is less than or equal to 0. + /// /// /// - /// A chunk can contain fewer elements than , specifically the final buffer of . + /// A chunk can contain fewer elements than , specifically the final buffer of . /// /// - /// This method is a synonym for . + /// This method is a synonym for . /// /// - /// Returned subsequences are buffered, but the overall operation is streamed.
+ /// Returned subsequences are buffered, but the overall operation is streamed.
///
///
public static IEnumerable> Buffer(this IEnumerable source, int count) @@ -33,23 +44,36 @@ public static IEnumerable> Buffer(this IEnumerable - /// Generates a sequence of buffers over the source sequence, with specified length and possible overlap. + /// Generates a sequence of buffers over the source sequence, with specified length and possible overlap. /// - /// Source sequence element type. - /// Source sequence. - /// Number of elements for allocated buffers. - /// Number of elements to skip between the start of consecutive buffers. - /// Sequence of buffers containing source sequence elements. - /// is . - /// or is less than - /// or equal to 0. + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Number of elements for allocated buffers. + /// + /// + /// Number of elements to skip between the start of consecutive buffers. + /// + /// + /// Sequence of buffers containing source sequence elements. + /// + /// + /// is . + /// + /// + /// or is less than or equal to 0. + /// /// /// - /// A chunk can contain fewer elements than , specifically the final buffers of . + /// A chunk can contain fewer elements than , specifically the final buffer(s) of + /// . /// /// - /// Returned subsequences are buffered, but the overall operation is streamed.
+ /// Returned subsequences are buffered, but the overall operation is streamed.
///
///
public static IEnumerable> Buffer(this IEnumerable source, int count, int skip) From 9f31752208fd6165a867705358534ed3be5d7dd6 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 18 Aug 2023 16:39:31 -0600 Subject: [PATCH 009/124] Update documentation for `Case` --- .../apidoc/SuperLinq.SuperEnumerable.Case.md | 13 +++ .../apidoc/SuperLinq/Case/Case1.linq | 27 ++++++ .../apidoc/SuperLinq/Case/Case2.linq | 28 ++++++ Source/SuperLinq/Case.cs | 86 +++++++++++++------ 4 files changed, 128 insertions(+), 26 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Case.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Case.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Case.md new file mode 100644 index 00000000..59c60ac0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Case.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.Case``2(System.Func{``0},System.Collections.Generic.IDictionary{``0,System.Collections.Generic.IEnumerable{``1}}) +example: [*content] +--- +The following code example demonstrates how to select which sequence to return values from, using `Case`. +[!code-csharp[](SuperLinq/Case/Case1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Case``2(System.Func{``0},System.Collections.Generic.IDictionary{``0,System.Collections.Generic.IEnumerable{``1}},System.Collections.Generic.IEnumerable{``1}) +example: [*content] +--- +The following code example demonstrates how to select which sequence to return values from, using `Case`. +[!code-csharp[](SuperLinq/Case/Case2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case1.linq new file mode 100644 index 00000000..0f33f799 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case1.linq @@ -0,0 +1,27 @@ + + SuperLinq + SuperLinq + + +var sequences = Enumerable.Range(1, 5) + .ToDictionary( + x => x, + x => Enumerable.Range(1, x)); + +// Use a function to select which sequence to return values from. +var selector = 1; +var result = SuperEnumerable + .Case( + () => selector, + sequences); + +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); +selector = 4; +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); +selector = 2; +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); + +// This code produces the following output: +// Selector: 1; result.Count(): 1. +// Selector: 4; result.Count(): 4. +// Selector: 2; result.Count(): 2. diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case2.linq new file mode 100644 index 00000000..2625800b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case2.linq @@ -0,0 +1,28 @@ + + SuperLinq + SuperLinq + + +var sequences = Enumerable.Range(1, 5) + .ToDictionary( + x => x, + x => Enumerable.Range(1, x)); + +// Use a function to select which sequence to return values from. +var selector = 1; +var result = SuperEnumerable + .Case( + () => selector, + sequences, + Enumerable.Range(1, 100)); + +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); +selector = 4; +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); +selector = 20; +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); + +// This code produces the following output: +// Selector: 1; result.Count(): 1. +// Selector: 4; result.Count(): 4. +// Selector: 20; result.Count(): 100. diff --git a/Source/SuperLinq/Case.cs b/Source/SuperLinq/Case.cs index 72fd82fb..0d3bd2c1 100644 --- a/Source/SuperLinq/Case.cs +++ b/Source/SuperLinq/Case.cs @@ -3,24 +3,38 @@ public static partial class SuperEnumerable { /// - /// Returns a sequence from a dictionary based on the result of evaluating a selector function. + /// Returns a sequence from a dictionary based on the result of evaluating a selector function. /// - /// Type of the selector value. - /// Result sequence element type. - /// Selector function used to pick a sequence from the given sources. - /// Dictionary mapping selector values onto resulting sequences. - /// The source sequence corresponding with the evaluated selector value; otherwise, an empty - /// sequence. - /// or is . + /// + /// Type of the selector value. + /// + /// + /// Result sequence element type. + /// + /// + /// Selector function used to pick a sequence from the given sources. + /// + /// + /// Dictionary mapping selector values onto resulting sequences. + /// + /// + /// The source sequence corresponding with the evaluated selector value; otherwise, an empty sequence. + /// + /// + /// or is . + /// + /// + /// (Thrown lazily) The sequence in selected by the result of is . + /// /// /// - /// is not evaluated until enumeration. The value returned will be used to select a - /// sequence from ; enumeration will continue with items from that sequence. + /// is not evaluated until enumeration. The value returned will be used to select a + /// sequence from ; enumeration will continue with items from that sequence. /// /// - /// If the value returned by is not present in , the resulting - /// sequence will be empty. + /// If the value returned by is not present in , the + /// resulting sequence will be empty. /// /// public static IEnumerable Case( @@ -32,21 +46,40 @@ public static IEnumerable Case( } /// - /// Returns a sequence from a dictionary based on the result of evaluating a selector function. + /// Returns a sequence from a dictionary based on the result of evaluating a selector function. /// - /// Type of the selector value. - /// Result sequence element type. - /// Selector function used to pick a sequence from the given sources. - /// Dictionary mapping selector values onto resulting sequences. - /// Default sequence to return in case there's no corresponding source for the computed - /// selector value. - /// The source sequence corresponding with the evaluated selector value; otherwise, an empty - /// sequence. - /// , , or is . + /// + /// Type of the selector value. + /// + /// + /// Result sequence element type. + /// + /// + /// Selector function used to pick a sequence from the given sources. + /// + /// + /// Dictionary mapping selector values onto resulting sequences. + /// + /// + /// Default sequence to return in case there's no corresponding source for the computed selector value. + /// + /// + /// The source sequence corresponding with the evaluated selector value; otherwise, the sequence. + /// + /// + /// , or is . + /// + /// + /// (Thrown lazily) The sequence in selected by the result of is . + /// /// - /// is not evaluated until enumeration. The value returned will be used to select a - /// sequence from ; enumeration will continue with items from that sequence. + /// + /// is not evaluated until enumeration. The value returned will be used to select a + /// sequence from ; enumeration will continue with items from that sequence. + /// /// public static IEnumerable Case( Func selector, @@ -68,6 +101,7 @@ static IEnumerable Core( if (!sources.TryGetValue(selector(), out var source)) source = defaultSource; + Guard.IsNotNull(source); foreach (var el in source) yield return el; } From 8725dc4e114f11b661bb2fb81b2804f028fa6b4a Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sun, 20 Aug 2023 07:30:13 -0500 Subject: [PATCH 010/124] Update documentation for `Catch` --- .../apidoc/SuperLinq.SuperEnumerable.Catch.md | 27 +++++ .../apidoc/SuperLinq/Catch/Catch1.linq | 21 ++++ .../apidoc/SuperLinq/Catch/Catch2.linq | 20 ++++ .../apidoc/SuperLinq/Catch/Catch3.linq | 24 ++++ .../apidoc/SuperLinq/Catch/Catch4.linq | 27 +++++ Source/SuperLinq/Catch.cs | 108 +++++++++++++----- 6 files changed, 196 insertions(+), 31 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Catch.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Catch.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Catch.md new file mode 100644 index 00000000..931aa984 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Catch.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.Catch``1(System.Collections.Generic.IEnumerable{System.Collections.Generic.IEnumerable{``0}}) +example: [*content] +--- +The following code example demonstrates how to use the `Catch` operator. +[!code-csharp[](SuperLinq/Catch/Catch4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Catch``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to use the `Catch` operator. +[!code-csharp[](SuperLinq/Catch/Catch2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Catch``1(System.Collections.Generic.IEnumerable{``0}[]) +example: [*content] +--- +The following code example demonstrates how to use the `Catch` operator. +[!code-csharp[](SuperLinq/Catch/Catch3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Catch``2(System.Collections.Generic.IEnumerable{``0},System.Func{``1,System.Collections.Generic.IEnumerable{``0}}) +example: [*content] +--- +The following code example demonstrates how to use the `Catch` operator. +[!code-csharp[](SuperLinq/Catch/Catch1.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch1.linq new file mode 100644 index 00000000..d1400737 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch1.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +// this sequence will throw an exception on the 6th element +var sequence = Enumerable.Range(1, 5).Select(i => i.ToString()) + .Concat(SuperEnumerable.Throw(new InvalidOperationException())); + +// Use a function to determine how to handle an exception +var result = sequence + .Catch( + (InvalidOperationException ex) => SuperEnumerable.Return(ex.Message)); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4, 5, Operation is not valid due to the current state of the object.] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch2.linq new file mode 100644 index 00000000..49515a78 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch2.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +// this sequence will throw an exception on the 6th element +var sequence = Enumerable.Range(1, 5) + .Concat(SuperEnumerable.Throw(new InvalidOperationException())); + +// Use a second sequence to continue in the case of an exception +var result = sequence + .Catch(Enumerable.Range(1, 5)); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch3.linq new file mode 100644 index 00000000..bef0bdb9 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch3.linq @@ -0,0 +1,24 @@ + + SuperLinq + SuperLinq + + +// this sequence will throw an exception on the 6th element +var sequence = Enumerable.Range(1, 5) + .Concat(SuperEnumerable.Throw(new InvalidOperationException())); + +// Use a series of sequences to enumerate until one completes successfully. +var result = SuperEnumerable + .Catch( + sequence, + sequence, + Enumerable.Range(1, 3), + Enumerable.Range(1, 10)); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch4.linq new file mode 100644 index 00000000..6286b7c6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch4.linq @@ -0,0 +1,27 @@ + + SuperLinq + SuperLinq + + +// this sequence will throw an exception on the 6th element +var sequence = Enumerable.Range(1, 5) + .Concat(SuperEnumerable.Throw(new InvalidOperationException())); + +// Use a series of sequences to enumerate until one completes successfully. +var result = SuperEnumerable + .Catch( + new List> + { + sequence, + sequence, + Enumerable.Range(1, 3), + Enumerable.Range(1, 10), + }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3] diff --git a/Source/SuperLinq/Catch.cs b/Source/SuperLinq/Catch.cs index ea2dda31..d66ca30c 100644 --- a/Source/SuperLinq/Catch.cs +++ b/Source/SuperLinq/Catch.cs @@ -3,18 +3,33 @@ public static partial class SuperEnumerable { /// - /// Creates a sequence that corresponds to the source sequence, concatenating it with the sequence resulting from - /// calling an exception handler function in case of an error. + /// Creates a sequence that corresponds to the source sequence, concatenating it with the sequence resulting + /// from calling an exception handler function in case of an error. /// - /// Source sequence element type. - /// Exception type to catch. - /// Source sequence. - /// Handler to invoke when an exception of the specified type occurs. - /// Source sequence, concatenated with an exception handler result sequence in case of an error. - /// or is . + /// + /// Source sequence element type. + /// + /// + /// Exception type to catch. + /// + /// + /// Source sequence. + /// + /// + /// Handler to invoke when an exception of the specified type occurs. + /// + /// + /// Source sequence, concatenated with an exception handler result sequence in case of an error. + /// + /// + /// or is . + /// + /// + /// (Thrown lazily) The sequence errSource returned by is . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// public static IEnumerable Catch( this IEnumerable source, @@ -56,17 +71,26 @@ static IEnumerable Core( } /// - /// Creates a sequence that returns the elements of the first sequence, switching to the second in case of an error. + /// Creates a sequence that returns the elements of the first sequence, switching to the second in case of an + /// error. /// - /// Source sequence element type. - /// First sequence. - /// Second sequence, concatenated to the result in case the first sequence completes - /// exceptionally. - /// The first sequence, followed by the second sequence in case an error is produced. - /// or is . + /// + /// Source sequence element type. + /// + /// + /// First sequence. + /// + /// + /// Second sequence, concatenated to the result in case the first sequence completes exceptionally. + /// + /// + /// The first sequence, followed by the second sequence in case an error is produced. + /// + /// + /// or is . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// public static IEnumerable Catch(this IEnumerable first, IEnumerable second) { @@ -77,14 +101,25 @@ public static IEnumerable Catch(this IEnumerable firs } /// - /// Creates a sequence by concatenating source sequences until a source sequence completes successfully. + /// Creates a sequence by concatenating source sequences until a source sequence completes successfully. /// - /// Source sequence element type. - /// Source sequences. - /// Sequence that continues to concatenate source sequences while errors occur. - /// is . + /// + /// Source sequence element type. + /// + /// + /// Source sequences. + /// + /// + /// Sequence that continues to concatenate source sequences while errors occur. + /// + /// + /// is . + /// + /// + /// (Thrown lazily) Any sequence source returned by is . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// public static IEnumerable Catch(params IEnumerable[] sources) { @@ -94,14 +129,25 @@ public static IEnumerable Catch(params IEnumerable[] } /// - /// Creates a sequence by concatenating source sequences until a source sequence completes successfully. + /// Creates a sequence by concatenating source sequences until a source sequence completes successfully. /// - /// Source sequence element type. - /// Source sequences. - /// Sequence that continues to concatenate source sequences while errors occur. - /// is . + /// + /// Source sequence element type. + /// + /// + /// Source sequences. + /// + /// + /// Sequence that continues to concatenate source sequences while errors occur. + /// + /// + /// is . + /// + /// + /// (Thrown lazily) Any sequence source returned by is . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// public static IEnumerable Catch(this IEnumerable> sources) { From 816e35ebead905834cf78d6b321ff8b50da0817a Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sun, 20 Aug 2023 15:55:48 -0500 Subject: [PATCH 011/124] Update documentation for `Choose` --- .../SuperLinq.SuperEnumerable.Choose.md | 6 +++ .../apidoc/SuperLinq/Choose/Choose.linq | 18 ++++++++ Source/SuperLinq/Choose.cs | 41 +++++++++---------- 3 files changed, 44 insertions(+), 21 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Choose.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Choose/Choose.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Choose.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Choose.md new file mode 100644 index 00000000..8a17fe33 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Choose.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Choose``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.ValueTuple{System.Boolean,``1}}) +example: [*content] +--- +The following code example demonstrates choose and project elements in a sequence using the `Choose` operator. +[!code-csharp[](SuperLinq/Choose/Choose.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Choose/Choose.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Choose/Choose.linq new file mode 100644 index 00000000..99d489fb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Choose/Choose.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = "O,l,2,3,4,S,6,7,B,9".Split(','); + +// Use a function to choose and project elements in the sequence +var result = sequence + .Choose(s => (int.TryParse(s, out var n), n)); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [2, 3, 4, 6, 7, 9] diff --git a/Source/SuperLinq/Choose.cs b/Source/SuperLinq/Choose.cs index 73eb2c7c..96449b4a 100644 --- a/Source/SuperLinq/Choose.cs +++ b/Source/SuperLinq/Choose.cs @@ -3,32 +3,31 @@ public static partial class SuperEnumerable { /// - /// Applies a function to each element of the source sequence and - /// returns a new sequence of result elements for source elements - /// where the function returns a couple (2-tuple) having a - /// as its first element and result as the second. + /// Applies a function to each element of the source sequence and returns a new sequence of result elements for + /// source elements where the function returns a couple (2-tuple) having a as its first + /// element and result as the second. /// /// - /// The type of the elements in . + /// The type of the elements in . + /// /// - /// The type of the elements in the returned sequence. - /// The source sequence. - /// The function that is applied to each source - /// element. - /// A sequence elements. + /// The type of the elements in the returned sequence. + /// + /// + /// The source sequence. + /// + /// + /// The function that is applied to each source element. + /// + /// + /// A sequence elements. + /// + /// + /// or is . + /// /// - /// This method uses deferred execution semantics and streams its - /// results. + /// This method uses deferred execution semantics and streams its results. /// - /// - /// (int.TryParse(s, out var n), n)); - /// ]]> - /// The xs variable will be a sequence of the integers 2, 3, 4, - /// 6, 7 and 9. - /// - public static IEnumerable Choose( this IEnumerable source, Func chooser) From c0cb16e08ee3d87038a3638ec3ec71c469c434db Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 23 Aug 2023 08:32:10 -0500 Subject: [PATCH 012/124] Update documentation for `CollectionEqual` --- ...perLinq.SuperEnumerable.CollectionEqual.md | 14 +++++ .../CollectionEqual/CollectionEqual1.linq | 17 +++++ .../CollectionEqual/CollectionEqual2.linq | 39 ++++++++++++ Source/SuperLinq/CollectionEqual.cs | 63 +++++++++---------- 4 files changed, 101 insertions(+), 32 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CollectionEqual.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CollectionEqual.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CollectionEqual.md new file mode 100644 index 00000000..92afcf50 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CollectionEqual.md @@ -0,0 +1,14 @@ +--- +uid: SuperLinq.SuperEnumerable.CollectionEqual``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to compare two collections using the `CollectionEqual` operator. +[!code-csharp[](SuperLinq/CollectionEqual/CollectionEqual1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.CollectionEqual``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to compare two collections using the `CollectionEqual` operator. +[!code-csharp[](SuperLinq/CollectionEqual/CollectionEqual2.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual1.linq new file mode 100644 index 00000000..b4e6127d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var pets1 = new List { new("Turbo", 2), new("Peanut", 8), }; +var pets2 = new List { new("Peanut", 8), new("Turbo", 2), }; + +// Determine if the two collections are equal, using the default equality comparer +var result = pets1.CollectionEqual(pets2); + +Console.WriteLine(result); + +// This code produces the following output: +// True + +record Pet(string Name, int Age); \ No newline at end of file diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual2.linq new file mode 100644 index 00000000..cbee8e3a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual2.linq @@ -0,0 +1,39 @@ + + SuperLinq + SuperLinq + + +var pets1 = new List { new("Turbo", 2), new("Peanut", 8), }; +var pets2 = new List { new("Peanut", 8), new("Turbo", 2), }; + +// Determine if the two collections are equal, using a custom equality comparer +var result = pets1 + .CollectionEqual( + pets2, + new PetComparer()); + +Console.WriteLine(result); + +// This code produces the following output: +// True + +class Pet +{ + public Pet(string name, int age) + { + this.Name = name; + this.Age = age; + } + + public string Name { get; } + public int Age { get; } +} + +class PetComparer : IEqualityComparer +{ + public bool Equals(Pet x, Pet y) => + x.Name == y.Name + && x.Age == y.Age; + public int GetHashCode(Pet x) => + HashCode.Combine(x.Name, x.Age); +} diff --git a/Source/SuperLinq/CollectionEqual.cs b/Source/SuperLinq/CollectionEqual.cs index e27ad45a..74cabe02 100644 --- a/Source/SuperLinq/CollectionEqual.cs +++ b/Source/SuperLinq/CollectionEqual.cs @@ -3,30 +3,30 @@ public static partial class SuperEnumerable { /// - /// Determines whether two collections are equal by comparing the elements by using - /// the default equality comparer for their type. + /// Determines whether two collections are equal by comparing the elements by using the default equality + /// comparer for their type. /// /// - /// The type of the elements of the input sequences. + /// The type of the elements of the input sequences. /// - /// An to compare to . + /// An to compare to . /// /// - /// An to compare to the sequence. + /// An to compare to the sequence. /// /// - /// if the two source sequences are of equal length and their corresponding - /// elements are equal according to the default equality comparer for their type; - /// otherwise, . + /// if the two source sequences are of equal length and their corresponding elements are + /// equal according to the default equality comparer for their type; otherwise, . /// - /// is null. - /// is null. + /// + /// or is . + /// /// /// - /// This method uses the default equality comparer for , , - /// determine whether two sequences have the same collection of elements. - /// A collection may have more than one of the same element, so this method - /// will compare the value and count of each element between both sequences. + /// This method uses the default equality comparer for , , determine whether two sequences have the same collection of elements. + /// A collection may have more than one of the same element, so this method will compare the value and count of + /// each element between both sequences. /// /// /// This method executes immediately. @@ -40,38 +40,37 @@ public static bool CollectionEqual( } /// - /// Determines whether two collections are equal by comparing the elements by using - /// a specified . + /// Determines whether two collections are equal by comparing the elements by using a specified . /// /// - /// The type of the elements of the input sequences. + /// The type of the elements of the input sequences. /// - /// An to compare to . + /// An to compare to . /// /// - /// An to compare to the sequence. + /// An to compare to the sequence. /// /// - /// An to use to compare elements. + /// An to use to compare elements. /// /// - /// if the two source sequences are of equal length and their corresponding - /// elements are equal according to the default equality comparer for their type; - /// otherwise, . + /// if the two source sequences are of equal length and their corresponding elements are + /// equal according to the default equality comparer for their type; otherwise, . /// - /// is null. - /// is null. + /// + /// or is . + /// /// /// - /// This method uses the provided equality comparer for to - /// determine whether two sequences have the same collection of elements. - /// A collection may have more than one of the same element, so this method - /// will compare the value and count of each element between both sequences. - /// If is , the default equality comparer, - /// , is used. + /// This method uses the provided equality comparer for to determine whether two + /// sequences have the same collection of elements. A collection may have more than one of the same element, so + /// this method will compare the value and count of each element between both sequences. If is , the default equality comparer, , is used. /// /// - /// This method executes immediately. + /// This method executes immediately. /// /// public static bool CollectionEqual( From 425c9af0b326b46838faa84c33979839ab422c0b Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 23 Aug 2023 09:32:03 -0500 Subject: [PATCH 013/124] Update documentation for `Consume` operator --- .../SuperLinq.SuperEnumerable.Consume.md | 6 +++++ .../apidoc/SuperLinq/Consume/Consume.linq | 13 ++++++++++ Source/SuperLinq/Consume.cs | 24 +++++++++++++++---- 3 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Consume.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Consume/Consume.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Consume.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Consume.md new file mode 100644 index 00000000..12d2eb73 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Consume.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Consume``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates consume a sequence using the `Consume` operator. +[!code-csharp[](SuperLinq/Consume/Consume.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Consume/Consume.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Consume/Consume.linq new file mode 100644 index 00000000..000797f0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Consume/Consume.linq @@ -0,0 +1,13 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5) + .Do(i => Console.Write($"{i}, ")); + +// Consume the provided sequence +sequence.Consume(); + +// This code produces the following output: +// 1, 2, 3, 4, 5, diff --git a/Source/SuperLinq/Consume.cs b/Source/SuperLinq/Consume.cs index 6916abfe..757f5080 100644 --- a/Source/SuperLinq/Consume.cs +++ b/Source/SuperLinq/Consume.cs @@ -3,12 +3,26 @@ public static partial class SuperEnumerable { /// - /// Completely consumes the given sequence. This method uses immediate execution, - /// and doesn't store any data during execution. + /// Completely consumes the given sequence. /// - /// Element type of the sequence - /// Source to consume - + /// + /// Element type of the sequence. + /// + /// + /// Source to consume. + /// + /// + /// is . + /// + /// + /// + /// The purpose of this method is to execute the operators for the provided , in the + /// event that the operators have side-effects. + /// + /// + /// This method executes immediately. + /// + /// public static void Consume(this IEnumerable source) { Guard.IsNotNull(source); From 5a0a748dabe97684c64fbdce60469675a11d73e7 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 23 Aug 2023 11:34:23 -0500 Subject: [PATCH 014/124] Update documentation for `CopyTo` --- .../SuperLinq.SuperEnumerable.CopyTo.md | 27 +++ .../apidoc/SuperLinq/CopyTo/CopyTo1.linq | 20 +++ .../apidoc/SuperLinq/CopyTo/CopyTo2.linq | 20 +++ .../apidoc/SuperLinq/CopyTo/CopyTo3.linq | 21 +++ .../apidoc/SuperLinq/CopyTo/CopyTo4.linq | 20 +++ Source/SuperLinq/CopyTo.cs | 155 ++++++++++++------ 6 files changed, 215 insertions(+), 48 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CopyTo.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CopyTo.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CopyTo.md new file mode 100644 index 00000000..ad9e37be --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CopyTo.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.CopyTo``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IList{``0}) +example: [*content] +--- +The following code example demonstrates how to copy data to a list using the `CopyTo` operator. +[!code-csharp[](SuperLinq/CopyTo/CopyTo1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.CopyTo``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IList{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to copy data to a list using the `CopyTo` operator. +[!code-csharp[](SuperLinq/CopyTo/CopyTo2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.CopyTo``1(System.Collections.Generic.IEnumerable{``0},System.Span{``0}) +example: [*content] +--- +The following code example demonstrates how to copy data to a span using the `CopyTo` operator. +[!code-csharp[](SuperLinq/CopyTo/CopyTo3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.CopyTo``1(System.Collections.Generic.IEnumerable{``0},``0[]) +example: [*content] +--- +The following code example demonstrates how to copy data to an array using the `CopyTo` operator. +[!code-csharp[](SuperLinq/CopyTo/CopyTo4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo1.linq new file mode 100644 index 00000000..13545728 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo1.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); +var destination = new List() { -1, -2, }; + +// Copy the provided sequence to a list +var result = sequence.CopyTo(destination); + +Console.WriteLine(result); +Console.WriteLine( + "[" + + string.Join(", ", destination) + + "]"); + +// This code produces the following output: +// 5 +// [1, 2, 3, 4, 5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo2.linq new file mode 100644 index 00000000..c5d7f020 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo2.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); +var destination = new List() { -1, -2, }; + +// Copy the provided sequence to a list at a specified index +var result = sequence.CopyTo(destination, 2); + +Console.WriteLine(result); +Console.WriteLine( + "[" + + string.Join(", ", destination) + + "]"); + +// This code produces the following output: +// 5 +// [-1, -2, 1, 2, 3, 4, 5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo3.linq new file mode 100644 index 00000000..14e6763a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo3.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); +var destination = new int[7]; +var span = destination.AsSpan(); + +// Copy the provided sequence to a span +var result = sequence.CopyTo(span[1..]); + +Console.WriteLine(result); +Console.WriteLine( + "[" + + string.Join(", ", destination) + + "]"); + +// This code produces the following output: +// 5 +// [0, 1, 2, 3, 4, 5, 0] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo4.linq new file mode 100644 index 00000000..dec6f199 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo4.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); +var destination = new int[5]; + +// Copy the provided sequence to an array +var result = sequence.CopyTo(destination); + +Console.WriteLine(result); +Console.WriteLine( + "[" + + string.Join(", ", destination) + + "]"); + +// This code produces the following output: +// 5 +// [1, 2, 3, 4, 5] diff --git a/Source/SuperLinq/CopyTo.cs b/Source/SuperLinq/CopyTo.cs index 91fc10db..70309da1 100644 --- a/Source/SuperLinq/CopyTo.cs +++ b/Source/SuperLinq/CopyTo.cs @@ -3,25 +3,37 @@ public static partial class SuperEnumerable { /// - /// Copies the contents of a sequence into a provided span. + /// Copies the contents of a sequence into a provided span. /// /// - /// The type of elements of - /// The source sequence. - /// The span that is the destination of the elements copied from . - /// The number of elements actually copied. - /// is . - /// is not long enough to hold the data from - /// sequence. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The span that is the destination of the elements copied from . + /// + /// + /// The number of elements actually copied. + /// + /// + /// is . + /// + /// + /// is not long enough to hold the data from sequence. + /// /// /// - /// All data from will be copied to if possible. If is shorter than , then any remaining elements will be untouched. If - /// is longer than , then an exception will be thrown. + /// All data from will be copied to if possible. + /// + /// + /// If is shorter than , then any remaining elements will be + /// untouched. If is longer than , then an exception will be + /// thrown. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int CopyTo(this IEnumerable source, Span span) @@ -60,25 +72,37 @@ public static int CopyTo(this IEnumerable source, Span - /// Copies the contents of a sequence into a provided span. + /// Copies the contents of a sequence into a provided span. /// /// - /// The type of elements of - /// The source sequence. - /// The span that is the destination of the elements copied from . - /// The number of elements actually copied. - /// is . - /// is not long enough to hold the data from - /// sequence. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The span that is the destination of the elements copied from . + /// + /// + /// The number of elements actually copied. + /// + /// + /// or is . + /// + /// + /// is not long enough to hold the data from sequence. + /// /// /// - /// All data from will be copied to if possible. If is shorter than , then any remaining elements will be untouched. If - /// is longer than , then an exception will be thrown. + /// All data from will be copied to if possible. /// /// - /// This operator executes immediately. + /// If is shorter than , then any remaining elements will be + /// untouched. If is longer than , then an exception will be + /// thrown. + /// + /// + /// This operator executes immediately. /// /// public static int CopyTo(this IEnumerable source, TSource[] array) @@ -128,22 +152,37 @@ private static int CopyTo(IEnumerable source, TSource[] array, } /// - /// Copies the contents of a sequence into a provided list. + /// Copies the contents of a sequence into a provided list. /// /// - /// The type of elements of - /// The source sequence. - /// The list that is the destination of the elements copied from . - /// The number of elements actually copied. - /// is . - /// is . + /// The type of elements of + /// + /// The source sequence. + /// + /// + /// The list that is the destination of the elements copied from . + /// + /// + /// The number of elements actually copied. + /// + /// + /// or is . + /// + /// + /// The is readonly, or does not allow increasing the size via + /// /// /// - /// All data from will be copied to , starting at position 0. + /// All data from will be copied to , starting at position 0. + /// + /// + /// If is shorter than , then any remaining elements will be + /// untouched. If is longer than , then an exception may be + /// thrown if the has a fixed size (an , for example). /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int CopyTo(this IEnumerable source, IList list) @@ -152,24 +191,44 @@ public static int CopyTo(this IEnumerable source, IList - /// Copies the contents of a sequence into a provided list. + /// Copies the contents of a sequence into a provided list. /// /// - /// The type of elements of - /// The source sequence. - /// The list that is the destination of the elements copied from . - /// The position in at which to start copying data - /// The number of elements actually copied. - /// is . - /// is . + /// The type of elements of + /// + /// The source sequence. + /// + /// + /// The list that is the destination of the elements copied from . + /// + /// + /// The position in at which to start copying data. + /// + /// + /// The number of elements actually copied. + /// + /// + /// or is . + /// + /// + /// is less than 0. + /// + /// + /// The is readonly, or does not allow increasing the size via + /// /// /// - /// All data from will be copied to , starting at position - /// . + /// All data from will be copied to , starting at position + /// . + /// + /// + /// If is shorter than , then any remaining elements will be + /// untouched. If is longer than , then an exception may be + /// thrown if the has a fixed size (an , for example). /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int CopyTo(this IEnumerable source, IList list, int index) From 673d06f5695a0925f866c89c35210114e6abb9ee Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 23 Aug 2023 17:53:55 -0500 Subject: [PATCH 015/124] Update documentation for `CountDown` --- .../SuperLinq.SuperEnumerable.CountDown.md | 14 ++++ .../SuperLinq/CountDown/CountDown1.linq | 17 +++++ .../SuperLinq/CountDown/CountDown2.linq | 17 +++++ Source/SuperLinq/CountDown.cs | 71 +++++++++++-------- 4 files changed, 88 insertions(+), 31 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountDown.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountDown.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountDown.md new file mode 100644 index 00000000..1c30e353 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountDown.md @@ -0,0 +1,14 @@ +--- +uid: SuperLinq.SuperEnumerable.CountDown``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to get a count down timer for a sequence, using the `CountDown` operator: +[!code-csharp[](SuperLinq/CountDown/CountDown1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.CountDown``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,System.Nullable{System.Int32},``1}) +example: [*content] +--- +The following code example demonstrates how to get a count down timer for a sequence, using the `CountDown` operator: +[!code-csharp[](SuperLinq/CountDown/CountDown2.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown1.linq new file mode 100644 index 00000000..c01bc233 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// Get a countdown counter for the the sequence +var result = sequence.CountDown(2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, ), (2, ), (3, ), (4, 1), (5, 0)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown2.linq new file mode 100644 index 00000000..f958eb16 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown2.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// Get a countdown counter for the the sequence +var result = sequence.CountDown(2, (item, cd) => new { Item = item, CountDown = cd?.ToString() ?? "null", }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ Item = 1, CountDown = null }, { Item = 2, CountDown = null }, { Item = 3, CountDown = null }, { Item = 4, CountDown = 1 }, { Item = 5, CountDown = 0 }] diff --git a/Source/SuperLinq/CountDown.cs b/Source/SuperLinq/CountDown.cs index c23c26af..61155148 100644 --- a/Source/SuperLinq/CountDown.cs +++ b/Source/SuperLinq/CountDown.cs @@ -3,31 +3,36 @@ public static partial class SuperEnumerable { /// - /// Provides a countdown counter for a given count of elements at the tail of the sequence where zero always - /// represents the last element, one represents the second-last element, two represents the third-last element and - /// so on. + /// Provides a countdown counter for a given count of elements at the tail of the sequence where zero always + /// represents the last element, one represents the second-last element, two represents the third-last element + /// and so on. /// /// - /// The type of elements of - /// The source sequence. - /// Count of tail elements of to count down. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// Count of tail elements of to count down. + /// /// - /// A sequence of tuples of the element and it's count from the end of the sequence. - /// + /// A sequence of tuples containing the element and it's count from the end of the sequence, or . + /// /// - /// is . + /// is . /// /// - /// is 0 or negative. + /// is 0 or negative. /// /// /// - /// This method uses deferred execution semantics and streams its results. At most, - /// elements of the source sequence may be buffered at any one time unless is a collection - /// or a list. + /// At most, elements of the source sequence may be buffered at any one time unless + /// is a collection or a list. /// /// - /// This operator executes immediately. + /// This method uses deferred execution semantics and streams its results. /// /// public static IEnumerable<(TSource item, int? count)> CountDown(this IEnumerable source, int count) @@ -36,37 +41,41 @@ public static partial class SuperEnumerable } /// - /// Provides a countdown counter for a given count of elements at the tail of the sequence where zero always - /// represents the last element, one represents the second-last element, two represents the third-last element and - /// so on. + /// Provides a countdown counter for a given count of elements at the tail of the sequence where zero always + /// represents the last element, one represents the second-last element, two represents the third-last element + /// and so on. /// /// - /// The type of elements of + /// The type of elements of + /// /// - /// The type of elements of the resulting sequence. - /// The source sequence. - /// Count of tail elements of to count down. + /// The type of elements of the resulting sequence. + /// + /// The source sequence. + /// + /// Count of tail elements of to count down. + /// /// - /// A function that receives the element and the current countdown value for the element and which returns those - /// mapped to a result returned in the resulting sequence. For elements before the last , - /// the countdown value is . + /// A function that receives the element and the current countdown value for the element and which returns those + /// mapped to a result returned in the resulting sequence. For elements before the last , the countdown value is . + /// /// - /// A sequence of results returned by . + /// A sequence of results returned by . /// /// - /// or is . + /// or is . /// /// - /// is 0 or negative. + /// is 0 or negative. /// /// /// - /// This method uses deferred execution semantics and streams its results. At most, - /// elements of the source sequence may be buffered at any one time unless is a collection - /// or a list. + /// At most, elements of the source sequence may be buffered at any one time unless + /// is a collection or a list. /// /// - /// This operator executes immediately. + /// This method uses deferred execution semantics and streams its results. /// /// public static IEnumerable CountDown( From 04cd8cfa6bb9f142cc30e0398c8c61d74e8cd405 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 23 Aug 2023 18:08:31 -0500 Subject: [PATCH 016/124] Update documentation for `CountBy` --- .../SuperLinq.SuperEnumerable.CountBy.md | 14 ++++ .../apidoc/SuperLinq/CountBy/CountBy1.linq | 17 +++++ .../apidoc/SuperLinq/CountBy/CountBy2.linq | 17 +++++ Source/SuperLinq/CountBy.cs | 76 ++++++++++++++----- 4 files changed, 105 insertions(+), 19 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountBy.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountBy.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountBy.md new file mode 100644 index 00000000..dfd64c1a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountBy.md @@ -0,0 +1,14 @@ +--- +uid: SuperLinq.SuperEnumerable.CountBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get the count by key in a sequence, using the `CountBy` operator: +[!code-csharp[](SuperLinq/CountBy/CountBy1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.CountBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to get the count by key in a sequence, using the `CountBy` operator: +[!code-csharp[](SuperLinq/CountBy/CountBy2.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy1.linq new file mode 100644 index 00000000..9f966e19 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 19); + +// Count elements in a sequence grouped by key +var result = sequence.CountBy(x => x % 3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, 7), (2, 6), (0, 6)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy2.linq new file mode 100644 index 00000000..939337a3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy2.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "a", "B", "c", "A", "b", "A", }; + +// Count elements in a sequence grouped by key +var result = sequence.CountBy(SuperEnumerable.Identity, StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(a, 3), (B, 2), (c, 1)] diff --git a/Source/SuperLinq/CountBy.cs b/Source/SuperLinq/CountBy.cs index 02e0ea88..755e3114 100644 --- a/Source/SuperLinq/CountBy.cs +++ b/Source/SuperLinq/CountBy.cs @@ -3,33 +3,71 @@ public static partial class SuperEnumerable { /// - /// Applies a key-generating function to each element of a sequence and returns a sequence of - /// unique keys and their number of occurrences in the original sequence. + /// Applies a key-generating function to each element of a sequence and returns a sequence of unique keys and + /// their number of occurrences in the original sequence. /// - /// Type of the elements of the source sequence. - /// Type of the projected element. - /// Source sequence. - /// Function that transforms each item of source sequence into a key to be compared against the others. - /// A sequence of unique keys and their number of occurrences in the original sequence. - + /// + /// Type of the elements of the source sequence. + /// + /// + /// Type of the projected element. + /// + /// + /// Source sequence. + /// + /// + /// Function that transforms each item of source sequence into a key to be compared against the others. + /// + /// + /// A sequence of unique keys and their number of occurrences in the original sequence. + /// + /// + /// or is . + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable<(TKey key, int count)> CountBy(this IEnumerable source, Func keySelector) { return source.CountBy(keySelector, comparer: null); } /// - /// Applies a key-generating function to each element of a sequence and returns a sequence of - /// unique keys and their number of occurrences in the original sequence. - /// An additional argument specifies a comparer to use for testing equivalence of keys. + /// Applies a key-generating function to each element of a sequence and returns a sequence of unique keys and + /// their number of occurrences in the original sequence. An additional argument specifies a comparer to use for + /// testing equivalence of keys. /// - /// Type of the elements of the source sequence. - /// Type of the projected element. - /// Source sequence. - /// Function that transforms each item of source sequence into a key to be compared against the others. - /// The equality comparer to use to determine whether or not keys are equal. - /// If null, the default equality comparer for is used. - /// A sequence of unique keys and their number of occurrences in the original sequence. - + /// + /// Type of the elements of the source sequence. + /// + /// + /// Type of the projected element. + /// + /// + /// Source sequence. + /// + /// + /// Function that transforms each item of source sequence into a key to be compared against the others. + /// + /// + /// The equality comparer to use to determine whether or not keys are equal. If null, the default equality + /// comparer for is used. + /// + /// + /// A sequence of unique keys and their number of occurrences in the original sequence. + /// + /// + /// or is . + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable<(TKey key, int count)> CountBy(this IEnumerable source, Func keySelector, IEqualityComparer? comparer) { Guard.IsNotNull(source); From a2b3cd878d38a449797b17910561fc34099590c7 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 24 Aug 2023 08:44:12 -0500 Subject: [PATCH 017/124] Update documentation for Count Methods --- .../SuperLinq.SuperEnumerable.AtLeast.md | 6 + .../SuperLinq.SuperEnumerable.AtMost.md | 6 + .../SuperLinq.SuperEnumerable.CompareCount.md | 6 + .../SuperLinq.SuperEnumerable.CountBetween.md | 6 + .../SuperLinq.SuperEnumerable.Exactly.md | 6 + .../apidoc/SuperLinq/AtLeast/AtLeast.linq | 21 ++ .../apidoc/SuperLinq/AtMost/AtMost.linq | 21 ++ .../SuperLinq/CompareCount/CompareCount.linq | 21 ++ .../SuperLinq/CountBetween/CountBetween.linq | 21 ++ .../apidoc/SuperLinq/Exactly/Exactly.linq | 21 ++ Source/SuperLinq/CountMethods.cs | 224 +++++++++++------- 11 files changed, 267 insertions(+), 92 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AtLeast.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AtMost.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CompareCount.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountBetween.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Exactly.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/AtLeast/AtLeast.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/AtMost/AtMost.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CompareCount/CompareCount.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBetween/CountBetween.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Exactly/Exactly.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AtLeast.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AtLeast.md new file mode 100644 index 00000000..f82ad805 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AtLeast.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.AtLeast``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to check that a sequence has a minimum size using `AtLeast`. +[!code-csharp[](SuperLinq/AtLeast/AtLeast.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AtMost.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AtMost.md new file mode 100644 index 00000000..d20e1706 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AtMost.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.AtMost``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to check that a sequence has a maximum size using `AtMost`. +[!code-csharp[](SuperLinq/AtMost/AtMost.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CompareCount.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CompareCount.md new file mode 100644 index 00000000..1f75cae1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CompareCount.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.CompareCount``2(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1}) +example: [*content] +--- +The following code example demonstrates to compare the length of two sequences using `CompareCount`. +[!code-csharp[](SuperLinq/CompareCount/CompareCount.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountBetween.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountBetween.md new file mode 100644 index 00000000..dcef2b45 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.CountBetween.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.CountBetween``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Int32) +example: [*content] +--- +The following code example demonstrates how to check that a sequence length is between two numbers using `CountBetween` +[!code-csharp[](SuperLinq/CountBetween/CountBetween.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Exactly.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Exactly.md new file mode 100644 index 00000000..42b803bb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Exactly.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Exactly``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to check that a sequence has as an exact length using `Exactly`. +[!code-csharp[](SuperLinq/Exactly/Exactly.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtLeast/AtLeast.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtLeast/AtLeast.linq new file mode 100644 index 00000000..a7f4479a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtLeast/AtLeast.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +foreach (var x in Enumerable.Range(3, 5)) +{ + // Check that a sequence has a minimum size + var result = sequence.AtLeast(x); + + Console.WriteLine($"AtLeast {x}: {result}"); +} + +// This code produces the following output: +// AtLeast 3: True +// AtLeast 4: True +// AtLeast 5: True +// AtLeast 6: False +// AtLeast 7: False diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtMost/AtMost.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtMost/AtMost.linq new file mode 100644 index 00000000..5994e792 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtMost/AtMost.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +foreach (var x in Enumerable.Range(3, 5)) +{ + // Check that a sequence has a maximum length + var result = sequence.AtMost(x); + + Console.WriteLine($"AtMost {x}: {result}"); +} + +// This code produces the following output: +// AtMost 3: False +// AtMost 4: False +// AtMost 5: True +// AtMost 6: True +// AtMost 7: True diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CompareCount/CompareCount.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CompareCount/CompareCount.linq new file mode 100644 index 00000000..67b716bb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CompareCount/CompareCount.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +foreach (var x in Enumerable.Range(3, 5)) +{ + // Compare the length of two sequences + var result = sequence.CompareCount(Enumerable.Range(1, x)); + + Console.WriteLine($"CompareCount {x}: {result}"); +} + +// This code produces the following output: +// CompareCount 3: 1 +// CompareCount 4: 1 +// CompareCount 5: 0 +// CompareCount 6: -1 +// CompareCount 7: -1 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBetween/CountBetween.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBetween/CountBetween.linq new file mode 100644 index 00000000..991a1b40 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBetween/CountBetween.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +foreach (var x in Enumerable.Range(3, 5)) +{ + // Check that a sequence has a length between two numbers + var result = sequence.CountBetween(x, x + 1); + + Console.WriteLine($"CountBetween {x}-{x + 1}: {result}"); +} + +// This code produces the following output: +// CountBetween 3-4: False +// CountBetween 4-5: True +// CountBetween 5-6: True +// CountBetween 6-7: False +// CountBetween 7-8: False diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exactly/Exactly.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exactly/Exactly.linq new file mode 100644 index 00000000..93a4cebb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exactly/Exactly.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +foreach (var x in Enumerable.Range(3, 5)) +{ + // Check that a sequence has an exact size + var result = sequence.Exactly(x); + + Console.WriteLine($"Exactly {x}: {result}"); +} + +// This code produces the following output: +// Exactly 3: False +// Exactly 4: False +// Exactly 5: True +// Exactly 6: False +// Exactly 7: False diff --git a/Source/SuperLinq/CountMethods.cs b/Source/SuperLinq/CountMethods.cs index bdc23bff..27ccc7d4 100644 --- a/Source/SuperLinq/CountMethods.cs +++ b/Source/SuperLinq/CountMethods.cs @@ -3,25 +3,33 @@ public static partial class SuperEnumerable { /// - /// Determines whether or not the number of elements in the sequence is greater than - /// or equal to the given integer. + /// Determines whether or not the number of elements in the sequence is greater than or equal to the given + /// integer. /// - /// Element type of sequence - /// The source sequence - /// The minimum number of items a sequence must have for this - /// function to return true - /// is null - /// is negative - /// if the number of elements in the sequence is greater than - /// or equal to the given integer or otherwise. - /// - /// - /// The result variable will contain . - /// - + /// + /// Element type of sequence + /// + /// + /// The source sequence + /// + /// + /// The minimum number of items a sequence must have for this function to return . + /// + /// + /// is . + /// + /// + /// is negative. + /// + /// + /// if the number of elements in the sequence is greater than or equal to the given + /// integer, otherwise. + /// + /// + /// + /// This method executes immediately. + /// + /// public static bool AtLeast(this IEnumerable source, int count) { Guard.IsGreaterThanOrEqualTo(count, 0); @@ -30,25 +38,33 @@ public static bool AtLeast(this IEnumerable source, int count) } /// - /// Determines whether or not the number of elements in the sequence is lesser than - /// or equal to the given integer. + /// Determines whether or not the number of elements in the sequence is lesser than or equal to the given + /// integer. /// - /// Element type of sequence - /// The source sequence - /// The maximum number of items a sequence must have for this - /// function to return true - /// is null - /// is negative - /// if the number of elements in the sequence is lesser than - /// or equal to the given integer or otherwise. - /// - /// - /// The result variable will contain . - /// - + /// + /// Element type of sequence + /// + /// + /// The source sequence + /// + /// + /// The maximum number of items a sequence must have for this function to return . + /// + /// + /// is . + /// + /// + /// is negative. + /// + /// + /// if the number of elements in the sequence is lesser than or equal to the given + /// integer, otherwise. + /// + /// + /// + /// This method executes immediately. + /// + /// public static bool AtMost(this IEnumerable source, int count) { Guard.IsGreaterThanOrEqualTo(count, 0); @@ -57,24 +73,32 @@ public static bool AtMost(this IEnumerable source, int count) } /// - /// Determines whether or not the number of elements in the sequence is equals to the given integer. + /// Determines whether or not the number of elements in the sequence is equals to the given integer. /// - /// Element type of sequence - /// The source sequence - /// The exactly number of items a sequence must have for this - /// function to return true - /// is null - /// is negative - /// if the number of elements in the sequence is equals - /// to the given integer or otherwise. - /// - /// - /// The result variable will contain . - /// - + /// + /// Element type of sequence + /// + /// + /// The source sequence + /// + /// + /// The exactly number of items a sequence must have for this function to return . + /// + /// + /// is . + /// + /// + /// is negative. + /// + /// + /// if the number of elements in the sequence is equals to the given integer, otherwise. + /// + /// + /// + /// This method executes immediately. + /// + /// public static bool Exactly(this IEnumerable source, int count) { Guard.IsGreaterThanOrEqualTo(count, 0); @@ -83,27 +107,36 @@ public static bool Exactly(this IEnumerable source, int count) } /// - /// Determines whether or not the number of elements in the sequence is between - /// an inclusive range of minimum and maximum integers. + /// Determines whether or not the number of elements in the sequence is between an inclusive range of minimum + /// and maximum integers. /// - /// Element type of sequence - /// The source sequence - /// The minimum number of items a sequence must have for this - /// function to return true - /// The maximum number of items a sequence must have for this - /// function to return true - /// is null - /// is negative or is less than min - /// if the number of elements in the sequence is between (inclusive) - /// the min and max given integers or otherwise. - /// - /// - /// The result variable will contain . - /// - + /// + /// Element type of sequence + /// + /// + /// The source sequence + /// + /// + /// The minimum number of items a sequence must have for this function to return . + /// + /// + /// The maximum number of items a sequence must have for this function to return . + /// + /// + /// is . + /// + /// + /// is negative, or is less than . + /// + /// + /// if the number of elements in the sequence is between (inclusive) the min and max + /// given integers, otherwise. + /// + /// + /// + /// This method executes immediately. + /// + /// public static bool CountBetween(this IEnumerable source, int min, int max) { Guard.IsGreaterThanOrEqualTo(min, 0); @@ -122,26 +155,33 @@ private static bool QuantityIterator(IEnumerable source, int limit, int mi } /// - /// Compares two sequences and returns an integer that indicates whether the first sequence - /// has fewer, the same or more elements than the second sequence. + /// Compares two sequences and returns an integer that indicates whether the first sequence has fewer, the same + /// or more elements than the second sequence. /// - /// Element type of the first sequence - /// Element type of the second sequence - /// The first sequence - /// The second sequence - /// is null - /// is null - /// -1 if the first sequence has the fewest elements, 0 if the two sequences have the same number of elements - /// or 1 if the first sequence has the most elements. - /// - /// - /// The result variable will contain 1. - /// - + /// + /// Element type of the first sequence. + /// + /// + /// Element type of the second sequence. + /// + /// + /// The first sequence. + /// + /// + /// The second sequence. + /// + /// + /// or is . + /// + /// + /// -1 if the first sequence has the fewest elements, 0 if the two sequences have the same number + /// of elements or 1 if the first sequence has the most elements. + /// + /// + /// + /// This method executes immediately. + /// + /// public static int CompareCount(this IEnumerable first, IEnumerable second) { Guard.IsNotNull(first); From 6c489141109b88a9bdb2b2a1283e01335ad76986 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 24 Aug 2023 18:56:39 -0500 Subject: [PATCH 018/124] Update documentation for `Defer` --- .../apidoc/SuperLinq.SuperEnumerable.Defer.md | 6 +++ .../apidoc/SuperLinq/Defer/Defer.linq | 28 +++++++++++++ Source/SuperLinq/Defer.cs | 40 +++++++++++++++---- 3 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Defer.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Defer/Defer.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Defer.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Defer.md new file mode 100644 index 00000000..dad18c22 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Defer.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Defer``1(System.Func{System.Collections.Generic.IEnumerable{``0}}) +example: [*content] +--- +The following code example demonstrates how to defer the execution of a method that returns an enumerable using `Defer`. +[!code-csharp[](SuperLinq/Defer/Defer.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Defer/Defer.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Defer/Defer.linq new file mode 100644 index 00000000..7ac256e0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Defer/Defer.linq @@ -0,0 +1,28 @@ + + SuperLinq + SuperLinq + + +var count = 3; + +// Use a function to create a sequence at execution time +var result = SuperEnumerable + .Defer(() => Enumerable.Range(1, count)); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// changing count changes the length of the sequence +// returned by the function given to Defer +count = 5; + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3] +// [1, 2, 3, 4, 5] diff --git a/Source/SuperLinq/Defer.cs b/Source/SuperLinq/Defer.cs index a5b1cfbb..4ea2b0b4 100644 --- a/Source/SuperLinq/Defer.cs +++ b/Source/SuperLinq/Defer.cs @@ -6,13 +6,36 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Creates an enumerable sequence based on an enumerable factory function. + /// Creates an enumerable sequence based on an enumerable factory function. /// - /// Result sequence element type. - /// Enumerable factory function. - /// Sequence that will invoke the enumerable factory upon iteration. - /// is . + /// + /// Result sequence element type. + /// + /// + /// Enumerable factory function. + /// + /// + /// Sequence that will invoke the enumerable factory upon iteration. + /// + /// + /// is . + /// + /// + /// (Thrown lazily) The sequence source returned by is . + /// + /// + /// + /// is not run until the sequence returned by is enumerated. At enumeration, is executed and the sequence returned is enumerated in a streaming manner and + /// values are returned similarly. + /// + /// + /// is executed each time the sequence returned by is enumerated. + /// + /// public static IEnumerable Defer(Func> enumerableFactory) { Guard.IsNotNull(enumerableFactory); @@ -21,7 +44,10 @@ public static IEnumerable Defer(Func> enu static IEnumerable Core(Func> enumerableFactory) { - foreach (var el in enumerableFactory()) + var source = enumerableFactory(); + Guard.IsNotNull(source); + + foreach (var el in source) yield return el; } } From 138ef1ea3995d6ee1f5d047eab736de28015fba1 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 26 Aug 2023 11:27:46 -0500 Subject: [PATCH 019/124] Update documentation for `DensePartialSort` --- ...erLinq.SuperEnumerable.DensePartialSort.md | 28 ++ ...Linq.SuperEnumerable.DensePartialSortBy.md | 28 ++ .../DensePartialSort/DensePartialSort1.linq | 47 ++ .../DensePartialSort/DensePartialSort2.linq | 47 ++ .../DensePartialSort/DensePartialSort3.linq | 32 ++ .../DensePartialSort/DensePartialSort4.linq | 33 ++ .../DensePartialSortBy1.linq | 32 ++ .../DensePartialSortBy2.linq | 33 ++ .../DensePartialSortBy3.linq | 33 ++ .../DensePartialSortBy4.linq | 34 ++ Source/SuperLinq/DensePartialSort.cs | 400 +++++++++++++----- 11 files changed, 630 insertions(+), 117 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DensePartialSort.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DensePartialSortBy.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DensePartialSort.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DensePartialSort.md new file mode 100644 index 00000000..87fba1e7 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DensePartialSort.md @@ -0,0 +1,28 @@ +--- +uid: SuperLinq.SuperEnumerable.DensePartialSort``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `DensePartialSort`. +[!code-csharp[](SuperLinq/DensePartialSort/DensePartialSort1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DensePartialSort``1(System.Collections.Generic.IEnumerable{``0},System.Int32,SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `DensePartialSort`. +[!code-csharp[](SuperLinq/DensePartialSort/DensePartialSort2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DensePartialSort``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Collections.Generic.IComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `DensePartialSort`. +[!code-csharp[](SuperLinq/DensePartialSort/DensePartialSort3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DensePartialSort``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Collections.Generic.IComparer{``0},SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `DensePartialSort`. +[!code-csharp[](SuperLinq/DensePartialSort/DensePartialSort4.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DensePartialSortBy.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DensePartialSortBy.md new file mode 100644 index 00000000..0bdc4acb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DensePartialSortBy.md @@ -0,0 +1,28 @@ +--- +uid: SuperLinq.SuperEnumerable.DensePartialSortBy``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `DensePartialSort`. +[!code-csharp[](SuperLinq/DensePartialSortBy/DensePartialSortBy1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DensePartialSortBy``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``1},SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `DensePartialSort`. +[!code-csharp[](SuperLinq/DensePartialSortBy/DensePartialSortBy2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DensePartialSortBy``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``1},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `DensePartialSort`. +[!code-csharp[](SuperLinq/DensePartialSortBy/DensePartialSortBy3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DensePartialSortBy``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``1},System.Collections.Generic.IComparer{``1},SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `DensePartialSort`. +[!code-csharp[](SuperLinq/DensePartialSortBy/DensePartialSortBy4.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort1.linq new file mode 100644 index 00000000..1b6d5e70 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort1.linq @@ -0,0 +1,47 @@ + + SuperLinq + SuperLinq + + +var sequence = new Item[] +{ + new(key: 5, text: "1"), + new(key: 5, text: "2"), + new(key: 4, text: "3"), + new(key: 4, text: "4"), + new(key: 3, text: "5"), + new(key: 3, text: "6"), + new(key: 2, text: "7"), + new(key: 2, text: "8"), + new(key: 1, text: "9"), + new(key: 1, text: "10"), +}; + +// Get the top N sets of items +var result = sequence.DensePartialSort(3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, 9), (1, 10), (2, 7), (2, 8), (3, 5), (3, 6)] + +class Item : IComparable +{ + public Item(int key, string text) + { + Key = key; + Text = text; + } + + public int Key { get; } + public string Text { get; } + + public int CompareTo(Item other) => + this.Key.CompareTo(other.Key); + + public override string ToString() => + $"({this.Key}, {this.Text})"; +} diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort2.linq new file mode 100644 index 00000000..29d89d5d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort2.linq @@ -0,0 +1,47 @@ + + SuperLinq + SuperLinq + + +var sequence = new Item[] +{ + new(key: 5, text: "1"), + new(key: 5, text: "2"), + new(key: 4, text: "3"), + new(key: 4, text: "4"), + new(key: 3, text: "5"), + new(key: 3, text: "6"), + new(key: 2, text: "7"), + new(key: 2, text: "8"), + new(key: 1, text: "9"), + new(key: 1, text: "10"), +}; + +// Get the top N sets of items +var result = sequence.DensePartialSort(3, OrderByDirection.Descending); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, 1), (5, 2), (4, 3), (4, 4), (3, 5), (3, 6)] + +class Item : IComparable +{ + public Item(int key, string text) + { + Key = key; + Text = text; + } + + public int Key { get; } + public string Text { get; } + + public int CompareTo(Item other) => + this.Key.CompareTo(other.Key); + + public override string ToString() => + $"({this.Key}, {this.Text})"; +} diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort3.linq new file mode 100644 index 00000000..362f7076 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort3.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N sets of items +var result = sequence + .DensePartialSort( + 3, + Comparer<(int key, string text)>.Create((x, y) => x.key.CompareTo(y.key))); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, 9), (1, 10), (2, 7), (2, 8), (3, 5), (3, 6)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort4.linq new file mode 100644 index 00000000..dbb96390 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort4.linq @@ -0,0 +1,33 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N sets of items +var result = sequence + .DensePartialSort( + 3, + Comparer<(int key, string text)>.Create((x, y) => x.key.CompareTo(y.key)), + OrderByDirection.Descending); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, 1), (5, 2), (4, 3), (4, 4), (3, 5), (3, 6)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy1.linq new file mode 100644 index 00000000..238b601c --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy1.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N sets of items +var result = sequence + .DensePartialSortBy( + 3, + x => x.key); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, 9), (1, 10), (2, 7), (2, 8), (3, 5), (3, 6)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy2.linq new file mode 100644 index 00000000..537c94b7 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy2.linq @@ -0,0 +1,33 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N sets of items +var result = sequence + .DensePartialSortBy( + 3, + x => x.key, + OrderByDirection.Descending); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, 1), (5, 2), (4, 3), (4, 4), (3, 5), (3, 6)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy3.linq new file mode 100644 index 00000000..0690b574 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy3.linq @@ -0,0 +1,33 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N sets of items +var result = sequence + .DensePartialSortBy( + 1, + x => x.key, + Comparer.Create((x, y) => (x % 2).CompareTo(y % 2))); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(4, 3), (4, 4), (2, 7), (2, 8)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy4.linq new file mode 100644 index 00000000..c1c02036 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy4.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N sets of items +var result = sequence + .DensePartialSortBy( + 1, + x => x.key, + Comparer.Create((x, y) => (x % 2).CompareTo(y % 2)), + OrderByDirection.Descending); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, 1), (5, 2), (3, 5), (3, 6), (1, 9), (1, 10)] diff --git a/Source/SuperLinq/DensePartialSort.cs b/Source/SuperLinq/DensePartialSort.cs index f941ddf6..79893099 100644 --- a/Source/SuperLinq/DensePartialSort.cs +++ b/Source/SuperLinq/DensePartialSort.cs @@ -5,23 +5,40 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Executes a partial sort of the top elements of a sequence, including ties. If is less than the total number of elements in , then this method will - /// improve performance. + /// Executes a partial sort of the top elements of a sequence, including ties. If + /// is less than the total number of elements in , then this + /// method will improve performance. /// - /// Type of elements in the sequence. - /// The source sequence. - /// Number of (maximum) elements to return. - /// A sequence containing at most top elements from source, in their ascending - /// order. - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// A sequence containing at most top elements from source, in their ascending order. + /// + /// + /// is . + /// + /// + /// is less than 1. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This is an O(n * log(K)) operation where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the + /// elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the + /// same key. /// /// public static IEnumerable DensePartialSort(this IEnumerable source, int count) @@ -30,24 +47,43 @@ public static IEnumerable DensePartialSort(this IEnumerable source, int } /// - /// Executes a partial sort of the top elements of a sequence, - /// including ties. If is less than the total number of elements in , then this method will improve performance. + /// Executes a partial sort of the top elements of a + /// sequence, including ties. If is less than the total number of elements in , then this method will improve performance. /// - /// Type of elements in the sequence. - /// The source sequence. - /// Number of (maximum) elements to return. - /// The direction in which to sort the elements - /// A sequence containing at most top elements from source, in the specified - /// order. - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// The direction in which to sort the elements + /// + /// + /// A sequence containing at most top elements from source, in the specified order. + /// + /// + /// is . + /// + /// + /// is less than 1. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This is an O(n * log(K)) operation where K is . + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// - /// This operator uses deferred execution and streams it results. + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the + /// elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the + /// same key. /// /// public static IEnumerable DensePartialSort( @@ -57,24 +93,43 @@ public static IEnumerable DensePartialSort( } /// - /// Executes a partial sort of the top elements of a sequence, including ties, using - /// to compare elements. If is less than the total number of - /// elements in , then this method will improve performance. + /// Executes a partial sort of the top elements of a sequence, including ties, using + /// to compare elements. If is less than the total number + /// of elements in , then this method will improve performance. /// - /// Type of elements in the sequence. - /// The source sequence. - /// Number of (maximum) elements to return. - /// A to compare elements. - /// A sequence containing at most top elements from source, in their ascending - /// order. - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// An to compare elements. + /// + /// + /// A sequence containing at most top elements from source, in their ascending order. + /// + /// + /// is . + /// + /// + /// is less than 1. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This is an O(n * log(K)) operation where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the + /// elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the + /// same key. /// /// public static IEnumerable DensePartialSort( @@ -85,25 +140,47 @@ public static IEnumerable DensePartialSort( } /// - /// Executes a partial sort of the top elements of a sequence, - /// including ties, using to compare elements. If is less than - /// the total number of elements in , then this method will improve performance. + /// Executes a partial sort of the top elements of a + /// sequence, including ties, using to compare elements. If + /// is less than the total number of elements in , then this method will improve + /// performance. /// - /// Type of elements in the sequence. - /// The source sequence. - /// Number of (maximum) elements to return. - /// A to compare elements. - /// The direction in which to sort the elements - /// A sequence containing at most top elements from source, in the specified - /// order. - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// A to compare elements. + /// + /// + /// The direction in which to sort the elements + /// + /// + /// A sequence containing at most top elements from source, in the specified order. + /// + /// + /// is . + /// + /// + /// is less than 1. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This is an O(n * log(K)) operation where K is . + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// - /// This operator uses deferred execution and streams it results. + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the + /// elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the + /// same key. /// /// public static IEnumerable DensePartialSort( @@ -114,26 +191,46 @@ public static IEnumerable DensePartialSort( } /// - /// Executes a partial sort of the top elements of a sequence, including ties, according to - /// the key for each element. If is less than the total number of elements in , then this method will improve performance. + /// Executes a partial sort of the top elements of a sequence, including ties, + /// according to the key for each element. If is less than the total number of elements + /// in , then this method will improve performance. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// Number of (maximum) elements to return. - /// A sequence containing at most top elements from source, in ascending order of - /// their keys. - /// is . - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// A sequence containing at most top elements from source, in ascending order of their + /// keys. + /// + /// + /// or is . + /// + /// + /// is less than 1. /// /// - /// This operation is an O(n * log(K)) where K is . + /// This is an O(n * log(K)) operation where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the + /// elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the + /// same key. /// /// public static IEnumerable DensePartialSortBy( @@ -144,27 +241,49 @@ public static IEnumerable DensePartialSortBy( } /// - /// Executes a partial sort of the top elements of a sequence, - /// including ties, according to the key for each element. If is less than the total number - /// of elements in , then this method will improve performance. + /// Executes a partial sort of the top elements of a + /// sequence, including ties, according to the key for each element. If is less than + /// the total number of elements in , then this method will improve performance. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// Number of (maximum) elements to return. - /// The direction in which to sort the elements - /// A sequence containing at most top elements from source, in the specified order - /// of their keys. - /// is . - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// The direction in which to sort the elements + /// + /// + /// A sequence containing at most top elements from source, in the specified order of + /// their keys. + /// + /// + /// or is . + /// + /// + /// is less than 1. /// /// - /// This operation is an O(n * log(K)) where K is . + /// This is an O(n * log(K)) operation where K is . + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// - /// This operator uses deferred execution and streams it results. + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the + /// elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the + /// same key. /// /// public static IEnumerable DensePartialSortBy( @@ -175,27 +294,50 @@ public static IEnumerable DensePartialSortBy( } /// - /// Executes a partial sort of the top elements of a sequence, including ties, according to - /// the key for each element, using to compare the keys. If is - /// less than the total number of elements in , then this method will improve performance. + /// Executes a partial sort of the top elements of a sequence, including ties, + /// according to the key for each element, using to compare the keys. If is less than the total number of elements in , then this method will + /// improve performance. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// Number of (maximum) elements to return. - /// A to compare elements. - /// A sequence containing at most top elements from source, in ascending order of - /// their keys. - /// is . - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// A to compare elements. + /// + /// + /// A sequence containing at most top elements from source, in ascending order of their + /// keys. + /// + /// + /// or is . + /// + /// + /// is less than 1. /// /// - /// This operation is an O(n * log(K)) where K is . + /// This is an O(n * log(K)) operation where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the + /// elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the + /// same key. /// /// public static IEnumerable DensePartialSortBy( @@ -207,29 +349,53 @@ public static IEnumerable DensePartialSortBy( } /// - /// Executes a partial sort of the top elements of a sequence, - /// including ties, according to the key for each element, using to compare the keys. If - /// is less than the total number of elements in , then this - /// method will improve performance. + /// Executes a partial sort of the top elements of a + /// sequence, including ties, according to the key for each element, using to + /// compare the keys. If is less than the total number of elements in , then this method will improve performance. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// Number of (maximum) elements to return. - /// A to compare elements. - /// The direction in which to sort the elements - /// A sequence containing at most top elements from source, in the specified order - /// of their keys. - /// is . - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// A to compare elements. + /// + /// + /// The direction in which to sort the elements + /// + /// + /// A sequence containing at most top elements from source, in the specified order of + /// their keys. + /// + /// or is . + /// + /// + /// is less than 1. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This is an O(n * log(K)) operation where K is . + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// - /// This operator uses deferred execution and streams it results. + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the + /// elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the + /// same key. /// /// public static IEnumerable DensePartialSortBy( From a9883d1f2386cccbdaa1a04208337d4f10596578 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 26 Aug 2023 15:22:25 -0500 Subject: [PATCH 020/124] Update documentation for `DistinctUntilChanged` --- ...nq.SuperEnumerable.DistinctUntilChanged.md | 27 ++++ .../DistinctUntilChanged1.linq | 52 ++++++++ .../DistinctUntilChanged2.linq | 57 +++++++++ .../DistinctUntilChanged3.linq | 32 +++++ .../DistinctUntilChanged4.linq | 34 +++++ Source/SuperLinq/DistinctUntilChanged.cs | 121 +++++++++++++----- 6 files changed, 294 insertions(+), 29 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DistinctUntilChanged.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DistinctUntilChanged.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DistinctUntilChanged.md new file mode 100644 index 00000000..f8ea57bc --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DistinctUntilChanged.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.DistinctUntilChanged``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to get distinct elements from a sequence using `DistinctUntilChanged`. +[!code-csharp[](SuperLinq/DistinctUntilChanged/DistinctUntilChanged1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DistinctUntilChanged``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to get distinct elements from a sequence using `DistinctUntilChanged`. +[!code-csharp[](SuperLinq/DistinctUntilChanged/DistinctUntilChanged2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DistinctUntilChanged``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get distinct elements from a sequence using `DistinctUntilChanged`. +[!code-csharp[](SuperLinq/DistinctUntilChanged/DistinctUntilChanged3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DistinctUntilChanged``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to get distinct elements from a sequence using `DistinctUntilChanged`. +[!code-csharp[](SuperLinq/DistinctUntilChanged/DistinctUntilChanged4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged1.linq new file mode 100644 index 00000000..af11f25a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged1.linq @@ -0,0 +1,52 @@ + + SuperLinq + SuperLinq + + +var sequence = new Item[] +{ + new(key: 3, text: "1"), + new(key: 3, text: "2"), + new(key: 2, text: "3"), + new(key: 2, text: "4"), + new(key: 1, text: "5"), + new(key: 1, text: "6"), + new(key: 3, text: "7"), + new(key: 3, text: "8"), + new(key: 2, text: "9"), + new(key: 2, text: "10"), + new(key: 1, text: "11"), + new(key: 1, text: "12"), +}; + +// Get distinct +var result = sequence.DistinctUntilChanged(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(3, 1), (2, 3), (1, 5), (3, 7), (2, 9), (1, 11)] + +class Item : IEquatable +{ + public Item(int key, string text) + { + Key = key; + Text = text; + } + + public int Key { get; } + public string Text { get; } + + public bool Equals(Item other) => + this.Key == other.Key; + + public override int GetHashCode() => + this.Key.GetHashCode(); + + public override string ToString() => + $"({this.Key}, {this.Text})"; +} diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged2.linq new file mode 100644 index 00000000..c65741a4 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged2.linq @@ -0,0 +1,57 @@ + + SuperLinq + SuperLinq + + +var sequence = new Item[] +{ + new(key: 3, text: "1"), + new(key: 3, text: "2"), + new(key: 2, text: "3"), + new(key: 2, text: "4"), + new(key: 1, text: "5"), + new(key: 1, text: "6"), + new(key: 3, text: "7"), + new(key: 3, text: "8"), + new(key: 2, text: "9"), + new(key: 2, text: "10"), + new(key: 1, text: "11"), + new(key: 1, text: "12"), +}; + +// Get distinct +var result = sequence + .DistinctUntilChanged( + new ItemComparer()); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(3, 1), (2, 3), (1, 5), (3, 7), (2, 9), (1, 11)] + +class Item +{ + public Item(int key, string text) + { + Key = key; + Text = text; + } + + public int Key { get; } + public string Text { get; } + + public override string ToString() => + $"({this.Key}, {this.Text})"; +} + +class ItemComparer : IEqualityComparer +{ + public bool Equals(Item x, Item y) => + x.Key == y.Key; + + public int GetHashCode(Item obj) => + obj.Key.GetHashCode(); +} diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged3.linq new file mode 100644 index 00000000..e2b588f0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged3.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 3, text: "1"), + (key: 3, text: "2"), + (key: 2, text: "3"), + (key: 2, text: "4"), + (key: 1, text: "5"), + (key: 1, text: "6"), + (key: 3, text: "7"), + (key: 3, text: "8"), + (key: 2, text: "9"), + (key: 2, text: "10"), + (key: 1, text: "11"), + (key: 1, text: "12"), +}; + +// Get distinct +var result = sequence + .DistinctUntilChanged(x => x.key); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(3, 1), (2, 3), (1, 5), (3, 7), (2, 9), (1, 11)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged4.linq new file mode 100644 index 00000000..efcb439e --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged4.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: "aa", text: "1"), + (key: "Aa", text: "2"), + (key: "AA", text: "3"), + (key: "BB", text: "4"), + (key: "bB", text: "5"), + (key: "Cc", text: "6"), + (key: "CC", text: "7"), + (key: "Aa", text: "8"), + (key: "aA", text: "9"), + (key: "bb", text: "10"), + (key: "bB", text: "11"), + (key: "CC", text: "12"), +}; + +// Get distinct +var result = sequence + .DistinctUntilChanged( + x => x.key, + StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(aa, 1), (BB, 4), (Cc, 6), (Aa, 8), (bb, 10), (CC, 12)] diff --git a/Source/SuperLinq/DistinctUntilChanged.cs b/Source/SuperLinq/DistinctUntilChanged.cs index c31b0c53..5eb775d8 100644 --- a/Source/SuperLinq/DistinctUntilChanged.cs +++ b/Source/SuperLinq/DistinctUntilChanged.cs @@ -3,25 +3,53 @@ public static partial class SuperEnumerable { /// - /// Returns consecutive distinct elements by using the default equality comparer to compare values. + /// Returns consecutive distinct elements by using the default equality comparer to compare values. /// - /// Source sequence element type. - /// Source sequence. - /// Sequence without adjacent non-distinct elements. - /// is . + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Sequence without adjacent non-distinct elements. + /// + /// + /// is . + /// + /// + /// + /// This method uses deferred execution semantics and streams its results. + /// + /// public static IEnumerable DistinctUntilChanged(this IEnumerable source) { return DistinctUntilChanged(source, Identity, comparer: null); } /// - /// Returns consecutive distinct elements by using the specified equality comparer to compare values. + /// Returns consecutive distinct elements by using the specified equality comparer to compare values. /// - /// Source sequence element type. - /// Source sequence. - /// Comparer used to compare values. - /// Sequence without adjacent non-distinct elements. - /// is . + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Comparer used to compare values. + /// + /// + /// Sequence without adjacent non-distinct elements. + /// + /// + /// is . + /// + /// + /// + /// This method uses deferred execution semantics and streams its results. + /// + /// public static IEnumerable DistinctUntilChanged(this IEnumerable source, IEqualityComparer? comparer) { Guard.IsNotNull(source); @@ -29,32 +57,67 @@ public static IEnumerable DistinctUntilChanged(this IEnumerabl } /// - /// Returns consecutive distinct elements based on a key value by using the specified equality comparer to compare - /// key values. + /// Returns consecutive distinct elements based on a key value by using the specified equality comparer to + /// compare key values. /// - /// Source sequence element type. - /// Key type. - /// Source sequence. - /// Key selector. - /// Sequence without adjacent non-distinct elements. - /// or is . + /// + /// Source sequence element type. + /// + /// + /// Key type. + /// + /// + /// Source sequence. + /// + /// + /// Key selector. + /// + /// + /// Sequence without adjacent non-distinct elements. + /// + /// + /// or is . + /// + /// + /// + /// This method uses deferred execution semantics and streams its results. + /// + /// public static IEnumerable DistinctUntilChanged(this IEnumerable source, Func keySelector) { return DistinctUntilChanged(source, keySelector, comparer: null); } /// - /// Returns consecutive distinct elements based on a key value by using the specified equality comparer to compare key values. + /// Returns consecutive distinct elements based on a key value by using the specified equality comparer to + /// compare key values. /// - /// Source sequence element type. - /// Key type. - /// Source sequence. - /// Key selector. - /// Comparer used to compare key values. - /// Sequence without adjacent non-distinct elements. - /// or is . + /// + /// Source sequence element type. + /// + /// + /// Key type. + /// + /// + /// Source sequence. + /// + /// + /// Key selector. + /// + /// + /// Comparer used to compare key values. + /// + /// + /// Sequence without adjacent non-distinct elements. + /// + /// + /// or is . + /// + /// + /// + /// This method uses deferred execution semantics and streams its results. + /// + /// public static IEnumerable DistinctUntilChanged(this IEnumerable source, Func keySelector, IEqualityComparer? comparer) { Guard.IsNotNull(source); From 101999c63a6ad88869f0b35b2b844d85b765309c Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 29 Aug 2023 20:01:55 -0500 Subject: [PATCH 021/124] Update documentation for `Do` --- .../apidoc/SuperLinq.SuperEnumerable.Do.md | 27 ++++ .../apidoc/SuperLinq/Do/Do1.linq | 18 +++ .../apidoc/SuperLinq/Do/Do2.linq | 21 +++ .../apidoc/SuperLinq/Do/Do3.linq | 25 ++++ .../apidoc/SuperLinq/Do/Do4.linq | 38 +++++ Source/SuperLinq/Do.cs | 134 +++++++++++++----- 6 files changed, 226 insertions(+), 37 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Do.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Do.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Do.md new file mode 100644 index 00000000..a080c761 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Do.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.Do``1(System.Collections.Generic.IEnumerable{``0},System.Action{``0}) +example: [*content] +--- +The following code example demonstrates how to lazily invoke actions for each element using `Do`. +[!code-csharp[](SuperLinq/Do/Do1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Do``1(System.Collections.Generic.IEnumerable{``0},System.Action{``0},System.Action) +example: [*content] +--- +The following code example demonstrates how to lazily invoke actions for each element using `Do`. +[!code-csharp[](SuperLinq/Do/Do2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Do``1(System.Collections.Generic.IEnumerable{``0},System.Action{``0},System.Action{System.Exception}) +example: [*content] +--- +The following code example demonstrates how to lazily invoke actions for each element using `Do`. +[!code-csharp[](SuperLinq/Do/Do3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Do``1(System.Collections.Generic.IEnumerable{``0},System.Action{``0},System.Action{System.Exception},System.Action) +example: [*content] +--- +The following code example demonstrates how to lazily invoke actions for each element using `Do`. +[!code-csharp[](SuperLinq/Do/Do4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do1.linq new file mode 100644 index 00000000..3099001a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// Execute an action for each element +var result = sequence + .Do(i => Console.Write($"{i}, ")); + +Console.WriteLine("Before"); +result.Consume(); +Console.WriteLine("After"); + +// This code produces the following output: +// Before +// 1, 2, 3, 4, 5, After diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do2.linq new file mode 100644 index 00000000..f1fcf5e8 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do2.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// Execute an action for each element, and on completion +var result = sequence + .Do( + i => Console.Write($"{i}, "), + () => Console.WriteLine("Completed")); + +Console.WriteLine("Before"); +result.Consume(); +Console.WriteLine("After"); + +// This code produces the following output: +// Before +// 1, 2, 3, 4, 5, Completed +// After diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do3.linq new file mode 100644 index 00000000..12466a0c --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do3.linq @@ -0,0 +1,25 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 4).Concat(SuperEnumerable.Throw(new InvalidOperationException())); + +// Execute an action for each element, on error, and on completion +var result = sequence + .Do( + i => Console.Write($"{i}, "), + ex => Console.WriteLine("Failed: " + ex.Message)); + +Console.WriteLine("Before"); +try +{ + result.Consume(); +} +catch (InvalidOperationException) {} +Console.WriteLine("After"); + +// This code produces the following output: +// Before +// 1, 2, 3, 4, Failed: Operation is not valid due to the current state of the object. +// After diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do4.linq new file mode 100644 index 00000000..3fdbe2d1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do4.linq @@ -0,0 +1,38 @@ + + SuperLinq + SuperLinq + + +var flag = false; +var sequence = SuperEnumerable.If( + () => flag, + Enumerable.Range(1, 5), + Enumerable.Range(1, 4).Concat(SuperEnumerable.Throw(new InvalidOperationException()))); + +// Execute an action for each element, on error, and on completion +var result = sequence + .Do( + i => Console.Write($"{i}, "), + ex => Console.WriteLine("Failed: " + ex.Message), + () => Console.WriteLine("Completed")); + +Console.WriteLine("Before 1"); +try +{ + result.Consume(); +} +catch (InvalidOperationException) {} +Console.WriteLine("After 1"); + +flag = true; +Console.WriteLine("Before 2"); +result.Consume(); +Console.WriteLine("After 2"); + +// This code produces the following output: +// Before 1 +// 1, 2, 3, 4, Failed: Operation is not valid due to the current state of the object. +// After 1 +// Before 2 +// 1, 2, 3, 4, 5, Completed +// After 2 diff --git a/Source/SuperLinq/Do.cs b/Source/SuperLinq/Do.cs index 1cc99262..9def7a39 100644 --- a/Source/SuperLinq/Do.cs +++ b/Source/SuperLinq/Do.cs @@ -3,16 +3,25 @@ public partial class SuperEnumerable { /// - /// Lazily invokes an action for each value in the sequence. + /// Lazily invokes an action for each value in the sequence. /// - /// Source sequence element type. - /// Source sequence. - /// Action to invoke for each element. - /// Sequence exhibiting the specified side-effects upon enumeration. - /// or is . + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Action to invoke for each element. + /// + /// + /// Sequence exhibiting the specified side-effects upon enumeration. + /// + /// + /// or is . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// public static IEnumerable Do(this IEnumerable source, Action onNext) { @@ -20,17 +29,29 @@ public static IEnumerable Do(this IEnumerable source, } /// - /// Lazily invokes an action for each value in the sequence, and executes an action for successful termination. + /// Lazily invokes an action for each value in the sequence, and executes an action for successful termination. /// - /// Source sequence element type. - /// Source sequence. - /// Action to invoke for each element. - /// Action to invoke on successful termination of the sequence. - /// Sequence exhibiting the specified side-effects upon enumeration. - /// , , or is . + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Action to invoke for each element. + /// + /// + /// Action to invoke on successful termination of the sequence. + /// + /// + /// Sequence exhibiting the specified side-effects upon enumeration. + /// + /// + /// , , or is . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// public static IEnumerable Do(this IEnumerable source, Action onNext, Action onCompleted) { @@ -52,17 +73,36 @@ private static IEnumerable DoCore(IEnumerable source, } /// - /// Lazily invokes an action for each value in the sequence, and executes an action upon exceptional termination. + /// Lazily invokes an action for each value in the sequence, and executes an action upon exceptional + /// termination. /// - /// Source sequence element type. - /// Source sequence. - /// Action to invoke for each element. - /// Action to invoke on exceptional termination of the sequence. - /// Sequence exhibiting the specified side-effects upon enumeration. - /// , , or is . + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Action to invoke for each element. + /// + /// + /// Action to invoke on exceptional termination of the sequence. + /// + /// + /// Sequence exhibiting the specified side-effects upon enumeration. + /// + /// + /// , , or is . + /// /// - /// This method uses deferred execution and streams its results. + /// + /// The exception is caught and passed to , and then it is re-thrown. Appropriate + /// error-handling is still required in order to safely consume the sequence. + /// + /// + /// This method uses deferred execution and streams its results. + /// /// public static IEnumerable Do(this IEnumerable source, Action onNext, Action onError) { @@ -70,19 +110,39 @@ public static IEnumerable Do(this IEnumerable source, } /// - /// Lazily invokes an action for each value in the sequence, and executes an action upon successful or exceptional - /// termination. + /// Lazily invokes an action for each value in the sequence, and executes an action upon successful or + /// exceptional termination. /// - /// Source sequence element type. - /// Source sequence. - /// Action to invoke for each element. - /// Action to invoke on exceptional termination of the sequence. - /// Action to invoke on successful termination of the sequence. - /// Sequence exhibiting the specified side-effects upon enumeration. - /// , , or is . + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Action to invoke for each element. + /// + /// + /// Action to invoke on exceptional termination of the sequence. + /// + /// + /// Action to invoke on successful termination of the sequence. + /// + /// + /// Sequence exhibiting the specified side-effects upon enumeration. + /// + /// + /// , , or is . + /// /// - /// This method uses deferred execution and streams its results. + /// + /// The exception is caught and passed to , and then it is re-thrown. Appropriate + /// error-handling is still required in order to safely consume the sequence. + /// + /// + /// This method uses deferred execution and streams its results. + /// /// public static IEnumerable Do(this IEnumerable source, Action onNext, Action onError, Action onCompleted) { From fa51802d1ac68be528b201fd4b28d2ac0f3dadbf Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 29 Aug 2023 20:50:33 -0500 Subject: [PATCH 022/124] Update documentation for `DoWhile` --- .../SuperLinq.SuperEnumerable.DoWhile.md | 6 ++++ .../apidoc/SuperLinq/DoWhile/DoWhile.linq | 27 ++++++++++++++++ Source/SuperLinq/DoWhile.cs | 32 ++++++++++++------- 3 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DoWhile.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DoWhile/DoWhile.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DoWhile.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DoWhile.md new file mode 100644 index 00000000..3a1e31ec --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.DoWhile.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.DoWhile``1(System.Collections.Generic.IEnumerable{``0},System.Func{System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to repeat a sequence as long as a condition is `true`, using `DoWhile`. +[!code-csharp[](SuperLinq/DoWhile/DoWhile.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DoWhile/DoWhile.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DoWhile/DoWhile.linq new file mode 100644 index 00000000..ca06a033 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DoWhile/DoWhile.linq @@ -0,0 +1,27 @@ + + SuperLinq + SuperLinq + + +var executionCount = 0; +var sequence = Enumerable.Range(1, 5) + .Do(_ => executionCount++); + +// Execute an action for each element +var loopCount = 0; +var result = sequence + .DoWhile(() => loopCount++ < 2); + +Console.WriteLine($"Before (execCount: {executionCount})"); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +Console.WriteLine($"After (execCount: {executionCount})"); + +// This code produces the following output: +// Before (execCount: 0) +// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5] +// After (execCount: 5) diff --git a/Source/SuperLinq/DoWhile.cs b/Source/SuperLinq/DoWhile.cs index cd1e9d4a..1a7517c6 100644 --- a/Source/SuperLinq/DoWhile.cs +++ b/Source/SuperLinq/DoWhile.cs @@ -3,22 +3,32 @@ public partial class SuperEnumerable { /// - /// Generates an enumerable sequence by repeating a source sequence as long as the given loop postcondition holds. + /// Generates an enumerable sequence by repeating a source sequence as long as the given loop postcondition + /// holds. /// - /// Source sequence element type. - /// Source sequence to repeat while the condition evaluates true. - /// Loop condition. - /// Sequence generated by repeating the given sequence until the condition evaluates to false. - /// or is . + /// + /// Source sequence element type. + /// + /// + /// Source sequence to repeat while the condition evaluates true. + /// + /// + /// Loop condition. + /// + /// + /// Sequence generated by repeating the given sequence until the condition evaluates to false. + /// + /// + /// or is . + /// /// /// - /// is evaluated lazily, once at the end of each loop of . + /// is evaluated lazily, once at the end of each loop of . /// /// - /// is cached via , so that it - /// is only iterated once during the first loop. Successive loops will enumerate the cache instead of . + /// is cached via , so that + /// it is only iterated once during the first loop. Successive loops will enumerate the cache instead of + /// . /// /// public static IEnumerable DoWhile(this IEnumerable source, Func condition) From 5449796dc9415344f41e5dc94b0aa5981142fc4a Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 30 Aug 2023 07:06:19 -0500 Subject: [PATCH 023/124] Update documentation for `DistinctBy` --- Source/SuperLinq/DistinctBy.cs | 90 +++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 28 deletions(-) diff --git a/Source/SuperLinq/DistinctBy.cs b/Source/SuperLinq/DistinctBy.cs index a2b71e11..37f02433 100644 --- a/Source/SuperLinq/DistinctBy.cs +++ b/Source/SuperLinq/DistinctBy.cs @@ -3,22 +3,38 @@ public static partial class SuperEnumerable { /// - /// Returns all distinct elements of the given source, where "distinctness" - /// is determined via a projection and the default equality comparer for the projected type. + /// Returns all distinct elements of the given source, where "distinctness" is determined via a projection and + /// the default equality comparer for the projected type. /// + /// + /// Type of the source sequence + /// + /// + /// Type of the projected element + /// + /// + /// Source sequence + /// + /// + /// Projection for determining "distinctness" + /// + /// + /// A sequence consisting of distinct elements from the source sequence, comparing them by the specified key + /// projection. + /// + /// + /// or is . + /// /// - /// This operator uses deferred execution and streams the results, although - /// a set of already-seen keys is retained. If a key is seen multiple times, - /// only the first element with that key is returned. + /// + /// This operator uses deferred execution and streams the results, although a set of already-seen keys is + /// retained. If a key is seen multiple times, only the first element with that key is returned. + /// + /// + /// This operator is implemented in the bcl as of net6. Source and binary compatibility should be retained + /// across net versions, but this method should be inaccessible in net6+. + /// /// - /// Type of the source sequence - /// Type of the projected element - /// Source sequence - /// Projection for determining "distinctness" - /// A sequence consisting of distinct elements from the source sequence, - /// comparing them by the specified key projection. - /// is . - /// is . #if NET6_0_OR_GREATER [Obsolete("This method has been implemented by the framework.")] public static IEnumerable DistinctBy( @@ -34,24 +50,42 @@ public static IEnumerable DistinctBy( } /// - /// Returns all distinct elements of the given source, where "distinctness" - /// is determined via a projection and the specified comparer for the projected type. + /// Returns all distinct elements of the given source, where "distinctness" is determined via a projection and + /// the default equality comparer for the projected type. /// + /// + /// Type of the source sequence + /// + /// + /// Type of the projected element + /// + /// + /// Source sequence + /// + /// + /// Projection for determining "distinctness" + /// + /// + /// The equality comparer to use to determine whether or not keys are equal. If , the + /// default equality comparer for is used. + /// + /// + /// A sequence consisting of distinct elements from the source sequence, comparing them by the specified key + /// projection. + /// + /// + /// or is . + /// /// - /// This operator uses deferred execution and streams the results, although - /// a set of already-seen keys is retained. If a key is seen multiple times, - /// only the first element with that key is returned. + /// + /// This operator uses deferred execution and streams the results, although a set of already-seen keys is + /// retained. If a key is seen multiple times, only the first element with that key is returned. + /// + /// + /// This operator is implemented in the bcl as of net6. Source and binary compatibility should be retained + /// across net versions, though but method should be inaccessible in net6+. + /// /// - /// Type of the source sequence - /// Type of the projected element - /// Source sequence - /// Projection for determining "distinctness" - /// The equality comparer to use to determine whether or not keys are equal. - /// If null, the default equality comparer for is used. - /// A sequence consisting of distinct elements from the source sequence, - /// comparing them by the specified key projection. - /// is . - /// is . #if NET6_0_OR_GREATER [Obsolete("This method has been implemented by the framework.")] public static IEnumerable DistinctBy( From eda7e8692c5e1b3233a14fcb333b8706ffad6d04 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 30 Aug 2023 07:06:32 -0500 Subject: [PATCH 024/124] Update documentation for `ElementAt` --- Source/SuperLinq/ElementAt.cs | 89 ++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 23 deletions(-) diff --git a/Source/SuperLinq/ElementAt.cs b/Source/SuperLinq/ElementAt.cs index d2d51773..cdf23f00 100644 --- a/Source/SuperLinq/ElementAt.cs +++ b/Source/SuperLinq/ElementAt.cs @@ -7,22 +7,46 @@ namespace SuperLinq; public static partial class SuperEnumerable { - /// Returns the element at a specified index in a sequence. - /// The type of the elements of . - /// An to return an element from. - /// The index of the element to retrieve, which is either from the start or the end. - /// is . - /// is outside the bounds of the sequence. - /// The element at the specified position in the sequence. + /// + /// Returns the element at a specified index in a sequence. + /// + /// + /// The type of the elements of . + /// + /// + /// An to return an element from. + /// + /// + /// The index of the element to retrieve, which is either from the start or the end. + /// + /// + /// is . + /// + /// + /// is outside the bounds of the sequence. + /// + /// + /// The element at the specified position in the sequence. + /// /// - /// If the type of implements , that implementation is used to obtain the element at the specified index. Otherwise, this method obtains the specified element. - /// This method throws an exception if is out of range. To instead return a default value when the specified index is out of range, use the method. + /// + /// If the type of implements , that implementation is used to + /// obtain the element at the specified index. Otherwise, this method obtains the specified element. + /// + /// + /// This method throws an exception if is out of range. To instead return a default + /// value when the specified index is out of range, use the method. + /// + /// + /// This operator is implemented in the bcl as of net6. Source and binary compatibility should be retained + /// across net versions, but this method should be inaccessible in net6+. + /// /// -#if !NET6_0_OR_GREATER - public static TSource ElementAt(this IEnumerable source, Index index) -#else +#if NET6_0_OR_GREATER [Obsolete("This method has been implemented by the framework.")] public static TSource ElementAt(IEnumerable source, Index index) +#else + public static TSource ElementAt(this IEnumerable source, Index index) #endif { Guard.IsNotNull(source); @@ -45,21 +69,40 @@ public static TSource ElementAt(IEnumerable source, Index inde return element; } - /// Returns the element at a specified index in a sequence or a default value if the index is out of range. - /// The type of the elements of . - /// An to return an element from. - /// The index of the element to retrieve, which is either from the start or the end. - /// is . - /// if is outside the bounds of the sequence; otherwise, the element at the specified position in the sequence. + /// + /// Returns the element at a specified index in a sequence or a default value if the index is out of range. + /// + /// + /// The type of the elements of . + /// + /// + /// An to return an element from. + /// + /// + /// The index of the element to retrieve, which is either from the start or the end. + /// + /// + /// is . + /// + /// + /// if is outside the bounds of the sequence; otherwise, the element at the specified position in the sequence. + /// /// - /// If the type of implements , that implementation is used to obtain the element at the specified index. Otherwise, this method obtains the specified element. - /// The default value for reference and nullable types is . + /// + /// If the type of implements , that implementation is used to + /// obtain the element at the specified index. Otherwise, this method obtains the specified element. + /// + /// + /// This operator is implemented in the bcl as of net6. Source and binary compatibility should be retained + /// across net versions, but this method should be inaccessible in net6+. + /// /// -#if !NET6_0_OR_GREATER - public static TSource? ElementAtOrDefault(this IEnumerable source, Index index) -#else +#if NET6_0_OR_GREATER [Obsolete("This method has been implemented by the framework.")] public static TSource? ElementAtOrDefault(IEnumerable source, Index index) +#else + public static TSource? ElementAtOrDefault(this IEnumerable source, Index index) #endif { Guard.IsNotNull(source); From e74b9614bf0e5f5dd480e811a953d8afc97090d3 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 30 Aug 2023 07:18:51 -0500 Subject: [PATCH 025/124] Update documentation for `EndsWith` --- .../SuperLinq.SuperEnumerable.EndsWith.md | 13 ++++ .../apidoc/SuperLinq/EndsWith/EndsWith1.linq | 15 +++++ .../apidoc/SuperLinq/EndsWith/EndsWith2.linq | 39 +++++++++++ Source/SuperLinq/EndsWith.cs | 67 ++++++++++++------- 4 files changed, 108 insertions(+), 26 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.EndsWith.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.EndsWith.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.EndsWith.md new file mode 100644 index 00000000..aa03494c --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.EndsWith.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.EndsWith``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to check that a sequence ends with another sequence using `EndsWith`. +[!code-csharp[](SuperLinq/EndsWith/EndsWith1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.EndsWith``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to check that a sequence ends with another sequence using `EndsWith`. +[!code-csharp[](SuperLinq/EndsWith/EndsWith2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith1.linq new file mode 100644 index 00000000..51b139c3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith1.linq @@ -0,0 +1,15 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// Determine if sequence ends with the ends sequence +var ends = Enumerable.Range(4, 2); +var result = sequence.EndsWith(ends); + +Console.WriteLine($"EndsWith: {result}"); + +// This code produces the following output: +// EndsWith: True diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith2.linq new file mode 100644 index 00000000..985743cd --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith2.linq @@ -0,0 +1,39 @@ + + SuperLinq + SuperLinq + + +var pets1 = new List { new("Turbo", 2), new("Peanut", 8), }; +var pets2 = new List { new("Peanut", 8), }; + +// Determine if pets1 ends with the pets2 sequence. +var result = pets1 + .EndsWith( + pets2, + new PetComparer()); + +Console.WriteLine($"EndsWith: {result}"); + +// This code produces the following output: +// EndsWith: True + +class Pet +{ + public Pet(string name, int age) + { + this.Name = name; + this.Age = age; + } + + public string Name { get; } + public int Age { get; } +} + +class PetComparer : IEqualityComparer +{ + public bool Equals(Pet x, Pet y) => + x.Name == y.Name + && x.Age == y.Age; + public int GetHashCode(Pet x) => + HashCode.Combine(x.Name, x.Age); +} diff --git a/Source/SuperLinq/EndsWith.cs b/Source/SuperLinq/EndsWith.cs index da7dedbb..790ebdf8 100644 --- a/Source/SuperLinq/EndsWith.cs +++ b/Source/SuperLinq/EndsWith.cs @@ -3,48 +3,63 @@ public static partial class SuperEnumerable { /// - /// Determines whether the end of the first sequence is equivalent to - /// the second sequence, using the default equality comparer. + /// Determines whether the end of the first sequence is equivalent to the second sequence, using the default + /// equality comparer. /// - /// Type of elements. - /// The sequence to check. - /// The sequence to compare to. + /// + /// Type of elements. + /// + /// + /// The sequence to check. + /// + /// + /// The sequence to compare to. + /// /// - /// if ends with elements - /// equivalent to . + /// if ends with elements equivalent to . /// + /// + /// or is . + /// /// - /// This is the equivalent of - /// and - /// it calls using - /// on pairs of elements at - /// the same index. + /// This is the equivalent of and it calls + /// using on pairs of + /// elements at the same index. /// - public static bool EndsWith(this IEnumerable first, IEnumerable second) { return EndsWith(first, second, comparer: null); } /// - /// Determines whether the end of the first sequence is equivalent to - /// the second sequence, using the specified element equality comparer. + /// Determines whether the end of the first sequence is equivalent to the second sequence, using the specified + /// element equality comparer. /// - /// Type of elements. - /// The sequence to check. - /// The sequence to compare to. - /// Equality comparer to use. + /// + /// Type of elements. + /// + /// + /// The sequence to check. + /// + /// + /// The sequence to compare to. + /// + /// + /// Equality comparer to use. + /// /// - /// if ends with elements - /// equivalent to . + /// if ends with elements equivalent to . /// + /// + /// or is . + /// /// - /// This is the equivalent of - /// and it calls - /// on pairs of - /// elements at the same index. + /// This is the equivalent of and it calls + /// using on pairs of + /// elements at the same index. /// - public static bool EndsWith(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) { Guard.IsNotNull(first); From dc80dc0eef4b5dd958b0e48da73892a6a4ea451b Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 30 Aug 2023 08:25:59 -0500 Subject: [PATCH 026/124] Update documentation for `Evaluate` --- .../SuperLinq.SuperEnumerable.Evaluate.md | 6 +++++ .../apidoc/SuperLinq/Evaluate/Evaluate.linq | 20 +++++++++++++++ Source/SuperLinq/Evaluate.cs | 25 ++++++++++++------- 3 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Evaluate.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Evaluate/Evaluate.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Evaluate.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Evaluate.md new file mode 100644 index 00000000..53a96060 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Evaluate.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Evaluate``1(System.Collections.Generic.IEnumerable{System.Func{``0}}) +example: [*content] +--- +The following code example demonstrates how to project a sequence of functions into their return values using `Evaluate`. +[!code-csharp[](SuperLinq/Evaluate/Evaluate.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Evaluate/Evaluate.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Evaluate/Evaluate.linq new file mode 100644 index 00000000..45743ecb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Evaluate/Evaluate.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +int Func1() => 3; +int Func2() => 5; +int Func3() => 1; + +// Execute an action for each element +var result = SuperEnumerable + .Evaluate(new[] { Func1, Func2, Func3 }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [3, 5, 1] diff --git a/Source/SuperLinq/Evaluate.cs b/Source/SuperLinq/Evaluate.cs index 93ee66ca..482c552d 100644 --- a/Source/SuperLinq/Evaluate.cs +++ b/Source/SuperLinq/Evaluate.cs @@ -3,18 +3,25 @@ public partial class SuperEnumerable { /// - /// Returns a sequence containing the values resulting from invoking (in order) each function in the source sequence of functions. + /// Returns a sequence containing the values resulting from invoking (in order) each function in the source + /// sequence of functions. /// + /// + /// The type of the object returned by the functions. + /// + /// + /// The functions to evaluate. + /// + /// + /// A sequence with results from invoking each function in the sequence. + /// + /// + /// is . + /// /// - /// This operator uses deferred execution and streams the results. - /// If the resulting sequence is enumerated multiple times, the functions will be - /// evaluated multiple times too. + /// This operator uses deferred execution and streams the results. If the resulting sequence is enumerated + /// multiple times, the functions will be evaluated multiple times too. /// - /// The type of the object returned by the functions. - /// The functions to evaluate. - /// A sequence with results from invoking . - /// When is . - public static IEnumerable Evaluate(this IEnumerable> functions) { Guard.IsNotNull(functions); From 4b0cd4480a5ea40823c03ed39cfb816a2dfa4c2d Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 30 Aug 2023 17:34:45 -0500 Subject: [PATCH 027/124] Update documentation for `ExceptBy` --- .../SuperLinq.SuperEnumerable.ExceptBy.md | 13 +++ .../apidoc/SuperLinq/ExceptBy/ExceptBy1.linq | 17 +++ .../apidoc/SuperLinq/ExceptBy/ExceptBy2.linq | 27 +++++ Source/SuperLinq/ExceptBy.cs | 103 +++++++++++------- 4 files changed, 122 insertions(+), 38 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ExceptBy.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ExceptBy.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ExceptBy.md new file mode 100644 index 00000000..ab03e464 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ExceptBy.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.ExceptBy``2(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to filter items from a sequence using a second sequence using `ExceptBy`. +[!code-csharp[](SuperLinq/ExceptBy/ExceptBy1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ExceptBy``2(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to filter items from a sequence using a second sequence using `ExceptBy`. +[!code-csharp[](SuperLinq/ExceptBy/ExceptBy2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy1.linq new file mode 100644 index 00000000..89f81f4f --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "aaa", "bb", "c", "dddd", }; + +// Determine if sequence ends with the ends sequence +var result = sequence.ExceptBy(new[] { "a", "b", }, s => s[0]); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [c, dddd] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy2.linq new file mode 100644 index 00000000..d49f7719 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy2.linq @@ -0,0 +1,27 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: "aaa", value: 1), + (key: "bb", value: 2), + (key: "c", value: 3), + (key: "dddd", value: 4), +}; + +// Determine if sequence ends with the ends sequence +var result = sequence + .ExceptBy( + new[] { (key: "A", value: 13), (key: "D", value: 14), }, + s => s.key[..1], + StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(bb, 2), (c, 3)] diff --git a/Source/SuperLinq/ExceptBy.cs b/Source/SuperLinq/ExceptBy.cs index a0b4d89b..3c9d9da9 100644 --- a/Source/SuperLinq/ExceptBy.cs +++ b/Source/SuperLinq/ExceptBy.cs @@ -3,56 +3,83 @@ public static partial class SuperEnumerable { /// - /// Returns the set of elements in the first sequence which aren't - /// in the second sequence, according to a given key selector. + /// Returns the set of elements in the first sequence which aren't in the second sequence, according to a given + /// key selector. /// + /// + /// The type of the elements in the input sequences. + /// + /// + /// The type of the key returned by . + /// + /// + /// The sequence of potentially included elements. + /// + /// + /// The sequence of elements whose keys may prevent elements in from being returned. + /// + /// + /// The mapping from source element to key. + /// + /// + /// A sequence of elements from whose key was not also a key for any element in + /// . + /// + /// + /// , , or is . + /// /// - /// This is a set operation; if multiple elements in have - /// equal keys, only the first such element is returned. - /// This operator uses deferred execution and streams the results, although - /// a set of keys from is immediately selected and retained. + /// + /// This is a set operation; if multiple elements in have equal keys, only the first + /// such element is returned. This operator uses deferred execution and streams the results, although a set of + /// keys from is immediately selected and retained. + /// /// - /// The type of the elements in the input sequences. - /// The type of the key returned by . - /// The sequence of potentially included elements. - /// The sequence of elements whose keys may prevent elements in - /// from being returned. - /// The mapping from source element to key. - /// A sequence of elements from whose key was not also a key for - /// any element in . - /// is . - /// is . - /// is . public static IEnumerable ExceptBy( this IEnumerable first, IEnumerable second, Func keySelector) - => ExceptBy(first, second, keySelector, keyComparer: default); + { + return ExceptBy(first, second, keySelector, keyComparer: default); + } /// - /// Returns the set of elements in the first sequence which aren't - /// in the second sequence, according to a given key selector. + /// Returns the set of elements in the first sequence which aren't in the second sequence, according to a given + /// key selector. /// /// - /// This is a set operation; if multiple elements in have - /// equal keys, only the first such element is returned. - /// This operator uses deferred execution and streams the results, although - /// a set of keys from is immediately selected and retained. + /// This is a set operation; if multiple elements in have equal keys, only the first + /// such element is returned. This operator uses deferred execution and streams the results, although a set of + /// keys from is immediately selected and retained. /// - /// The type of the elements in the input sequences. - /// The type of the key returned by . - /// The sequence of potentially included elements. - /// The sequence of elements whose keys may prevent elements in - /// from being returned. - /// The mapping from source element to key. - /// The equality comparer to use to determine whether or not keys are equal. - /// If null, the default equality comparer for is used. - /// A sequence of elements from whose key was not also a key for - /// any element in . - /// is . - /// is . - /// is . - /// is . + /// + /// The type of the elements in the input sequences. + /// + /// + /// The type of the key returned by . + /// + /// + /// The sequence of potentially included elements. + /// + /// + /// The sequence of elements whose keys may prevent elements in from being returned. + /// + /// + /// The mapping from source element to key. + /// + /// + /// The equality comparer to use to determine whether or not keys are equal. If null, the default equality + /// comparer for is used. + /// + /// + /// A sequence of elements from whose key was not also a key for any element in + /// . + /// + /// + /// , , or , or is . + /// public static IEnumerable ExceptBy( this IEnumerable first, IEnumerable second, From 6fdbb128531fcf63b60aef0766d53333e9dd5f99 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 30 Aug 2023 20:40:32 -0500 Subject: [PATCH 028/124] Update documentation for `EquiZip` --- .../SuperLinq.SuperEnumerable.EquiZip.md | 42 +++ .../apidoc/SuperLinq/EquiZip/EquiZip1.linq | 18 ++ .../apidoc/SuperLinq/EquiZip/EquiZip2.linq | 21 ++ .../apidoc/SuperLinq/EquiZip/EquiZip3.linq | 22 ++ .../apidoc/SuperLinq/EquiZip/EquiZip4.linq | 23 ++ .../apidoc/SuperLinq/EquiZip/EquiZip5.linq | 24 ++ .../apidoc/SuperLinq/EquiZip/EquiZip6.linq | 31 ++ Generators/SuperLinq.Generator/EquiZip.sbntxt | 82 +++-- .../EquiZip.g.cs | 288 ++++++++++++------ 9 files changed, 426 insertions(+), 125 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.EquiZip.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip5.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip6.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.EquiZip.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.EquiZip.md new file mode 100644 index 00000000..bbc99e50 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.EquiZip.md @@ -0,0 +1,42 @@ +--- +uid: SuperLinq.SuperEnumerable.EquiZip``2(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1}) +example: [*content] +--- +The following code example demonstrates how to use the `EquiZip` to merge two sequences of exactly equal length. +[!code-csharp[](SuperLinq/EquiZip/EquiZip1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.EquiZip``3(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2}) +example: [*content] +--- +The following code example demonstrates how to use the `EquiZip` to merge two sequences of exactly equal length. +[!code-csharp[](SuperLinq/EquiZip/EquiZip3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.EquiZip``3(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Func{``0,``1,``2}) +example: [*content] +--- +The following code example demonstrates how to use the `EquiZip` to merge three sequences of exactly equal length. +[!code-csharp[](SuperLinq/EquiZip/EquiZip2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.EquiZip``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3}) +example: [*content] +--- +The following code example demonstrates how to use the `EquiZip` to merge three sequences of exactly equal length. +[!code-csharp[](SuperLinq/EquiZip/EquiZip5.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.EquiZip``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Func{``0,``1,``2,``3}) +example: [*content] +--- +The following code example demonstrates how to use the `EquiZip` to merge four sequences of exactly equal length. +[!code-csharp[](SuperLinq/EquiZip/EquiZip4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.EquiZip``5(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Func{``0,``1,``2,``3,``4}) +example: [*content] +--- +The following code example demonstrates how to use the `EquiZip` to merge four sequences of exactly equal length. +[!code-csharp[](SuperLinq/EquiZip/EquiZip6.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip1.linq new file mode 100644 index 00000000..3726a59e --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, 4, }; + +// Determine if sequence ends with the ends sequence +var result = seq1.EquiZip(seq2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(aaa, 1), (bb, 2), (c, 3), (ddd, 4)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip2.linq new file mode 100644 index 00000000..b458a5d8 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip2.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, 4, }; + +// Determine if sequence ends with the ends sequence +var result = seq1 + .EquiZip( + seq2, + (a, b) => new { Key = a, Value = b, }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ Key = aaa, Value = 1 }, { Key = bb, Value = 2 }, { Key = c, Value = 3 }, { Key = ddd, Value = 4 }] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip3.linq new file mode 100644 index 00000000..f9ead98d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip3.linq @@ -0,0 +1,22 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, 4, }; +var seq3 = new[] { 20, 5, 7, 12 }; + +// Determine if sequence ends with the ends sequence +var result = seq1 + .EquiZip( + seq2, + seq3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(aaa, 1, 20), (bb, 2, 5), (c, 3, 7), (ddd, 4, 12)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip4.linq new file mode 100644 index 00000000..40fc9b05 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip4.linq @@ -0,0 +1,23 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, 4, }; +var seq3 = new[] { 20, 5, 7, 12 }; + +// Determine if sequence ends with the ends sequence +var result = seq1 + .EquiZip( + seq2, + seq3, + (a, b, c) => new { A = a, B = b, C = c, }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ A = aaa, B = 1, C = 20 }, { A = bb, B = 2, C = 5 }, { A = c, B = 3, C = 7 }, { A = ddd, B = 4, C = 12 }] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip5.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip5.linq new file mode 100644 index 00000000..24bd5419 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip5.linq @@ -0,0 +1,24 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, 4, }; +var seq3 = new[] { 20, 5, 7, 12 }; +var seq4 = new[] { "zz", "yyyy", "xxx", "w", }; + +// Determine if sequence ends with the ends sequence +var result = seq1 + .EquiZip( + seq2, + seq3, + seq4); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(aaa, 1, 20, zz), (bb, 2, 5, yyyy), (c, 3, 7, xxx), (ddd, 4, 12, w)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip6.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip6.linq new file mode 100644 index 00000000..ce407d1d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip6.linq @@ -0,0 +1,31 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, 4, }; +var seq3 = new[] { 20, 5, 7, 12 }; +var seq4 = new[] { "zz", "yyyy", "xxx", "w", }; + +// Determine if sequence ends with the ends sequence +var result = seq1 + .EquiZip( + seq2, + seq3, + seq4, + (a, b, c, d) => new + { + A = a, + B = b, + C = c, + D = d, + }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ A = aaa, B = 1, C = 20, D = zz }, { A = bb, B = 2, C = 5, D = yyyy }, { A = c, B = 3, C = 7, D = xxx }, { A = ddd, B = 4, C = 12, D = w }] diff --git a/Generators/SuperLinq.Generator/EquiZip.sbntxt b/Generators/SuperLinq.Generator/EquiZip.sbntxt index 37459b70..c79c755c 100644 --- a/Generators/SuperLinq.Generator/EquiZip.sbntxt +++ b/Generators/SuperLinq.Generator/EquiZip.sbntxt @@ -11,29 +11,41 @@ namespace SuperLinq; public static partial class SuperEnumerable { {{~ for $i in 2..4 ~}} - /// + /// /// - /// Applies a specified function to the corresponding elements of {{ $ordinals[$i] }} sequences, - /// producing a sequence of the results. + /// Applies a specified function to the corresponding elements of second sequences, producing a sequence of the + /// results. + /// /// - /// The resulting sequence has the same length as the input sequences. - /// If the input sequences are of different lengths, an exception is thrown. - /// - /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . - /// - /// This method uses deferred execution and stream its results. - /// - /// or any of the input sequences is null. - /// - /// Any of the input sequences are shorter than the others. + /// The resulting sequence has the same length as the input sequences. If the input sequences are of different + /// lengths, an exception is thrown. + /// + /// + /// + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// + /// + /// This method uses deferred execution and stream its results. + /// + /// + /// or any of the input sequences is . + /// + /// + /// Any of the input sequences are shorter than the others. /// {{~ for $j in 1..$i ~}} - /// The type of the elements of . - /// The {{ $ordinals[$j] }} sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The {{ $ordinals[$j] }} sequence of elements. + /// {{~ end ~}} public static global::System.Collections.Generic.IEnumerable EquiZip<{{ for $j in 1..$i }}T{{ $cardinals[$j] }}, {{ end }}TResult>(this {{~ for $j in 1..$i ~}} @@ -109,23 +121,29 @@ public static partial class SuperEnumerable } } - /// - /// Joins the corresponding elements of {{ $ordinals[$i] }} sequences, - /// producing a sequence of tuples containing them. + /// + /// Joins the corresponding elements of second sequences, producing a sequence of tuples containing them. /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. + /// + /// A sequence of + /// containing corresponding elements from each of the sequences. + /// /// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. /// - /// Any of the input sequences is null. - /// - /// Any of the input sequences are shorter than the others. - /// + /// + /// Any of the input sequences is null. + /// + /// + /// Any of the input sequences are shorter than the others. + /// {{~ for $j in 1..$i ~}} - /// The type of the elements of . - /// The {{ $ordinals[$j] }} sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The {{ $ordinals[$j] }} sequence of elements. + /// {{~ end ~}} public static global::System.Collections.Generic.IEnumerable<({{~ for $j in 1..$i ~}}T{{ $cardinals[$j] }}{{ if !for.last }},{{ end }}{{ end }})> EquiZip<{{~ for $j in 1..$i ~}}T{{ $cardinals[$j] }}{{ if !for.last }},{{ end }}{{ end }}>(this diff --git a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/EquiZip.g.cs b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/EquiZip.g.cs index 93d5c011..1fc71574 100644 --- a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/EquiZip.g.cs +++ b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/EquiZip.g.cs @@ -4,28 +4,44 @@ public static partial class SuperEnumerable { /// /// - /// Applies a specified function to the corresponding elements of second sequences, - /// producing a sequence of the results. + /// Applies a specified function to the corresponding elements of second sequences, producing a sequence of the + /// results. + /// /// - /// The resulting sequence has the same length as the input sequences. - /// If the input sequences are of different lengths, an exception is thrown. + /// The resulting sequence has the same length as the input sequences. If the input sequences are of different + /// lengths, an exception is thrown. + /// /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. /// - /// or any of the input sequences is null. + /// + /// or any of the input sequences is . + /// /// - /// Any of the input sequences are shorter than the others. + /// Any of the input sequences are shorter than the others. /// - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable EquiZip(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -61,23 +77,33 @@ public static partial class SuperEnumerable } /// - /// Joins the corresponding elements of second sequences, - /// producing a sequence of tuples containing them. + /// Joins the corresponding elements of second sequences, producing a sequence of tuples containing them. /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. + /// + /// A sequence of + /// containing corresponding elements from each of the sequences. + /// /// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. /// - /// Any of the input sequences is null. + /// + /// Any of the input sequences is null. + /// /// - /// Any of the input sequences are shorter than the others. + /// Any of the input sequences are shorter than the others. /// - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(TFirst, TSecond)> EquiZip(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second) => EquiZip(first, second, global::System.ValueTuple.Create); private class EquiZipIterator : ListIterator { @@ -123,30 +149,50 @@ protected override TResult ElementAt(int index) /// /// - /// Applies a specified function to the corresponding elements of third sequences, - /// producing a sequence of the results. + /// Applies a specified function to the corresponding elements of second sequences, producing a sequence of the + /// results. + /// /// - /// The resulting sequence has the same length as the input sequences. - /// If the input sequences are of different lengths, an exception is thrown. + /// The resulting sequence has the same length as the input sequences. If the input sequences are of different + /// lengths, an exception is thrown. + /// /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. /// - /// or any of the input sequences is null. + /// + /// or any of the input sequences is . + /// /// - /// Any of the input sequences are shorter than the others. + /// Any of the input sequences are shorter than the others. /// - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable EquiZip(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -186,25 +232,39 @@ protected override TResult ElementAt(int index) } /// - /// Joins the corresponding elements of third sequences, - /// producing a sequence of tuples containing them. + /// Joins the corresponding elements of second sequences, producing a sequence of tuples containing them. /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. + /// + /// A sequence of + /// containing corresponding elements from each of the sequences. + /// /// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. /// - /// Any of the input sequences is null. + /// + /// Any of the input sequences is null. + /// /// - /// Any of the input sequences are shorter than the others. + /// Any of the input sequences are shorter than the others. /// - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(TFirst, TSecond, TThird)> EquiZip(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third) => EquiZip(first, second, third, global::System.ValueTuple.Create); private class EquiZipIterator : ListIterator { @@ -257,32 +317,56 @@ protected override TResult ElementAt(int index) /// /// - /// Applies a specified function to the corresponding elements of fourth sequences, - /// producing a sequence of the results. + /// Applies a specified function to the corresponding elements of second sequences, producing a sequence of the + /// results. + /// /// - /// The resulting sequence has the same length as the input sequences. - /// If the input sequences are of different lengths, an exception is thrown. + /// The resulting sequence has the same length as the input sequences. If the input sequences are of different + /// lengths, an exception is thrown. + /// /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. /// - /// or any of the input sequences is null. + /// + /// or any of the input sequences is . + /// /// - /// Any of the input sequences are shorter than the others. + /// Any of the input sequences are shorter than the others. /// - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable EquiZip(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -326,27 +410,45 @@ protected override TResult ElementAt(int index) } /// - /// Joins the corresponding elements of fourth sequences, - /// producing a sequence of tuples containing them. + /// Joins the corresponding elements of second sequences, producing a sequence of tuples containing them. /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. + /// + /// A sequence of + /// containing corresponding elements from each of the sequences. + /// /// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. /// - /// Any of the input sequences is null. + /// + /// Any of the input sequences is null. + /// /// - /// Any of the input sequences are shorter than the others. + /// Any of the input sequences are shorter than the others. /// - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(TFirst, TSecond, TThird, TFourth)> EquiZip(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth) => EquiZip(first, second, third, fourth, global::System.ValueTuple.Create); private class EquiZipIterator : ListIterator { From ba97d6f38ee836b2a591ece91a6dd4e5de0b60f2 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 31 Aug 2023 09:20:41 -0500 Subject: [PATCH 029/124] Update documentation for `FallbackIfEmpty` --- ...perLinq.SuperEnumerable.FallbackIfEmpty.md | 13 ++++ .../FallbackIfEmpty/FallbackIfEmpty1.linq | 30 +++++++++ .../FallbackIfEmpty/FallbackIfEmpty2.linq | 32 +++++++++ Source/SuperLinq/FallbackIfEmpty.cs | 67 +++++++++++++------ 4 files changed, 122 insertions(+), 20 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FallbackIfEmpty.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FallbackIfEmpty.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FallbackIfEmpty.md new file mode 100644 index 00000000..eea4c05a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FallbackIfEmpty.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.FallbackIfEmpty``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to use `FallbackIfEmpty` to use a fallback sequence if the primary sequence is empty. +[!code-csharp[](SuperLinq/FallbackIfEmpty/FallbackIfEmpty2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FallbackIfEmpty``1(System.Collections.Generic.IEnumerable{``0},``0[]) +example: [*content] +--- +The following code example demonstrates how to use `FallbackIfEmpty` to use a fallback sequence if the primary sequence is empty. +[!code-csharp[](SuperLinq/FallbackIfEmpty/FallbackIfEmpty1.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty1.linq new file mode 100644 index 00000000..34a409d9 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty1.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var flag = false; +var sequence = SuperEnumerable.Defer( + () => + { + if (flag) return Enumerable.Empty(); + flag = true; + return Enumerable.Range(1, 5); + }); + +// Replace a sequence if it is empty. +var result = sequence.FallbackIfEmpty(10, 11, 12); + +Console.WriteLine( + "Non-Empty: [" + + string.Join(", ", result) + + "]"); + +Console.WriteLine( + "Empty: [" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// Non-Empty: [1, 2, 3, 4, 5] +// Empty: [10, 11, 12] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty2.linq new file mode 100644 index 00000000..39bc99ef --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty2.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var flag = false; +var sequence = SuperEnumerable.Defer( + () => + { + if (flag) return Enumerable.Empty(); + flag = true; + return Enumerable.Range(1, 5); + }); + +// Replace a sequence if it is empty. +var result = sequence + .FallbackIfEmpty( + Enumerable.Range(20, 3)); + +Console.WriteLine( + "Non-Empty: [" + + string.Join(", ", result) + + "]"); + +Console.WriteLine( + "Empty: [" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// Non-Empty: [1, 2, 3, 4, 5] +// Empty: [20, 21, 22] diff --git a/Source/SuperLinq/FallbackIfEmpty.cs b/Source/SuperLinq/FallbackIfEmpty.cs index ccf10731..4a9df3ee 100644 --- a/Source/SuperLinq/FallbackIfEmpty.cs +++ b/Source/SuperLinq/FallbackIfEmpty.cs @@ -3,38 +3,65 @@ public static partial class SuperEnumerable { /// - /// Returns the elements of a sequence, but if it is empty then - /// returns an alternate sequence from an array of values. + /// Returns the elements of a sequence, but if it is empty then returns an alternate sequence from an array of + /// values. /// - /// The type of the elements in the sequences. - /// The source sequence. - /// The array that is returned as the alternate - /// sequence if is empty. + /// + /// The type of the elements in the sequences. + /// + /// + /// The source sequence. + /// + /// + /// The array that is returned as the alternate sequence if is empty. + /// /// - /// An that containing fallback values - /// if is empty; otherwise, . + /// An that containing fallback values if is empty; + /// otherwise, . /// - /// is . - /// is . + /// + /// or is . + /// + /// + /// + /// The length of is not evaluated until enumeration. is + /// enumerated; if there is at least one item, the elements of will be streamed in a + /// deferred manner. If there are no items in , the items in + /// will be streamed. + /// + /// public static IEnumerable FallbackIfEmpty(this IEnumerable source, params T[] fallback) { return source.FallbackIfEmpty((IEnumerable)fallback); } /// - /// Returns the elements of a sequence, but if it is empty then - /// returns an alternate sequence of values. + /// Returns the elements of a sequence, but if it is empty then returns an alternate sequence of values. /// - /// The type of the elements in the sequences. - /// The source sequence. - /// The alternate sequence that is returned - /// if is empty. + /// + /// The type of the elements in the sequences. + /// + /// + /// The source sequence. + /// + /// + /// The alternate sequence that is returned if is empty. + /// /// - /// An that containing fallback values - /// if is empty; otherwise, . + /// An that containing fallback values if is empty; + /// otherwise, . /// - /// is . - /// is . + /// + /// or is . + /// + /// + /// + /// The length of is not evaluated until enumeration. is + /// enumerated; if there is at least one item, the elements of will be streamed using + /// deferred execution. If there are no items in , then + /// will be streamed using deferred execution. + /// + /// public static IEnumerable FallbackIfEmpty(this IEnumerable source, IEnumerable fallback) { Guard.IsNotNull(source); From 5e513b819098f6d96e4ce02e534b8ee738929077 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 31 Aug 2023 12:29:59 -0500 Subject: [PATCH 030/124] Update documentation for `Exclude` --- .../SuperLinq.SuperEnumerable.Exclude.md | 6 ++++ .../apidoc/SuperLinq/Exclude/Exclude.linq | 18 +++++++++++ Source/SuperLinq/Exclude.cs | 31 ++++++++++++++----- 3 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Exclude.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Exclude/Exclude.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Exclude.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Exclude.md new file mode 100644 index 00000000..3e005d86 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Exclude.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Exclude``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Int32) +example: [*content] +--- +The following code example demonstrates how to exclude a contiguous set of elements from a sequence using `Exclude`. +[!code-csharp[](SuperLinq/Exclude/Exclude.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exclude/Exclude.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exclude/Exclude.linq new file mode 100644 index 00000000..56829d8d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exclude/Exclude.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Execute an action for each element +var result = sequence + .Exclude(3, 5); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 9, 10] diff --git a/Source/SuperLinq/Exclude.cs b/Source/SuperLinq/Exclude.cs index 80b555b6..a8d417e3 100644 --- a/Source/SuperLinq/Exclude.cs +++ b/Source/SuperLinq/Exclude.cs @@ -3,17 +3,32 @@ public static partial class SuperEnumerable { /// - /// Excludes a contiguous number of elements from a sequence starting at a given index. + /// Excludes a contiguous number of elements from a sequence starting at a given index. /// - /// The type of the elements of the sequence - /// The sequence to exclude elements from - /// The zero-based index at which to begin excluding elements - /// The number of elements to exclude - /// A sequence that excludes the specified portion of elements - /// is null. + /// + /// The type of the elements of the sequence + /// + /// + /// The sequence to exclude elements from + /// + /// + /// The zero-based index at which to begin excluding elements + /// + /// + /// The number of elements to exclude + /// + /// + /// A sequence that excludes the specified portion of elements + /// + /// + /// is . + /// /// - /// or is less than 0. + /// or is less than 0. /// + /// + /// This method uses deferred execution and streams its results. + /// public static IEnumerable Exclude(this IEnumerable sequence, int startIndex, int count) { Guard.IsNotNull(sequence); From c192b36292dbb275f13e2aef032aa5a26a83e9a9 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 31 Aug 2023 14:57:12 -0500 Subject: [PATCH 031/124] Update documentation for `FillBackward` --- .../SuperLinq.SuperEnumerable.FillBackward.md | 20 ++++ .../SuperLinq/FillBackward/FillBackward1.linq | 17 ++++ .../SuperLinq/FillBackward/FillBackward2.linq | 19 ++++ .../SuperLinq/FillBackward/FillBackward3.linq | 20 ++++ Source/SuperLinq/FillBackward.cs | 94 +++++++++++-------- 5 files changed, 131 insertions(+), 39 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FillBackward.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FillBackward.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FillBackward.md new file mode 100644 index 00000000..10332767 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FillBackward.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.FillBackward``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to fill in missing elements with following elements using `FillBackward`. +[!code-csharp[](SuperLinq/FillBackward/FillBackward1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FillBackward``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to fill in missing elements with following elements using `FillBackward`. +[!code-csharp[](SuperLinq/FillBackward/FillBackward2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FillBackward``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean},System.Func{``0,``0,``0}) +example: [*content] +--- +The following code example demonstrates how to fill in missing elements with following elements using `FillBackward`. +[!code-csharp[](SuperLinq/FillBackward/FillBackward3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward1.linq new file mode 100644 index 00000000..8cbb5eca --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = new int?[] { null, null, 1, 2, null, null, null, 3, 4, null, null, }; + +// Fill in missing elements from later elements +var result = sequence.FillBackward(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 1, 1, 2, 3, 3, 3, 3, 4, , ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward2.linq new file mode 100644 index 00000000..6e11f824 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward2.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Fill in missing elements from later elements +var result = sequence + .FillBackward( + i => i % 3 < 2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [2, 2, 5, 5, 5, 8, 8, 8, 9, 10] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward3.linq new file mode 100644 index 00000000..fd50eb98 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward3.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Fill in missing elements from later elements +var result = sequence + .FillBackward( + i => i % 3 < 2, + (cur, nxt) => cur * nxt * 100); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [200, 2, 1500, 2000, 5, 4800, 5600, 8, 9, 10] diff --git a/Source/SuperLinq/FillBackward.cs b/Source/SuperLinq/FillBackward.cs index 0e94c467..d794e285 100644 --- a/Source/SuperLinq/FillBackward.cs +++ b/Source/SuperLinq/FillBackward.cs @@ -5,20 +5,24 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Returns a sequence with each null reference or value in the source - /// replaced with the following non-null reference or value in - /// that sequence. + /// Returns a sequence with each null reference or value in the source replaced with the following non-null + /// reference or value in that sequence. /// - /// The source sequence. - /// Type of the elements in the source sequence. + /// + /// The source sequence. + /// + /// + /// Type of the elements in the source sequence. + /// /// - /// An with null references or values - /// replaced. + /// An with null references or values replaced. /// + /// + /// is . + /// /// - /// This method uses deferred execution semantics and streams its - /// results. If references or values are null at the end of the - /// sequence then they remain null. + /// This method uses deferred execution semantics and streams its results. If references or values are at the end of the sequence then they remain . /// public static IEnumerable FillBackward(this IEnumerable source) { @@ -26,22 +30,28 @@ public static partial class SuperEnumerable } /// - /// Returns a sequence with each missing element in the source replaced - /// with the following non-missing element in that sequence. An - /// additional parameter specifies a function used to determine if an - /// element is considered missing or not. + /// Returns a sequence with each missing element in the source replaced with the following non-missing element + /// in that sequence. An additional parameter specifies a function used to determine if an element is considered + /// missing or not. /// - /// The source sequence. - /// The function used to determine if - /// an element in the sequence is considered missing. - /// Type of the elements in the source sequence. + /// + /// The source sequence. + /// + /// + /// The function used to determine if an element in the sequence is considered missing. + /// + /// + /// Type of the elements in the source sequence. + /// /// - /// An with missing values replaced. + /// An with missing values replaced. /// + /// + /// or is . + /// /// - /// This method uses deferred execution semantics and streams its - /// results. If elements are missing at the end of the sequence then - /// they remain missing. + /// This method uses deferred execution semantics and streams its results. If elements are missing at the end of + /// the sequence then they remain missing. /// public static IEnumerable FillBackward(this IEnumerable source, Func predicate) { @@ -54,27 +64,33 @@ public static IEnumerable FillBackward(this IEnumerable source, Func - /// Returns a sequence with each missing element in the source replaced - /// with the following non-missing element in that sequence. Additional - /// parameters specify two functions, one used to determine if an - /// element is considered missing or not and another to provide the - /// replacement for the missing element. + /// Returns a sequence with each missing element in the source replaced with the following non-missing element + /// in that sequence. Additional parameters specify two functions, one used to determine if an element is + /// considered missing or not and another to provide the replacement for the missing element. /// - /// The source sequence. - /// The function used to determine if - /// an element in the sequence is considered missing. - /// The function used to produce the element - /// that will replace the missing one. Its first argument receives the - /// current element considered missing while the second argument - /// receives the next non-missing element. - /// Type of the elements in the source sequence. + /// + /// The source sequence. + /// + /// + /// The function used to determine if an element in the sequence is considered missing. + /// + /// + /// The function used to produce the element that will replace the missing one. Its first argument receives the + /// current element considered missing while the second argument receives the next non-missing element. + /// + /// + /// Type of the elements in the source sequence. + /// /// - /// An with missing elements filled. + /// An with missing elements filled. /// + /// + /// , , or is . + /// /// - /// This method uses deferred execution semantics and streams its - /// results. If elements are missing at the end of the sequence then - /// they remain missing. + /// This method uses deferred execution semantics and streams its results. If elements are missing at the end of + /// the sequence then they remain missing. /// public static IEnumerable FillBackward(this IEnumerable source, Func predicate, Func fillSelector) { From 335ec9be5d3d104ed5594b4aae1f3458174511dd Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 1 Sep 2023 05:57:11 -0500 Subject: [PATCH 032/124] Update documentation for `FillForward` --- .../SuperLinq.SuperEnumerable.FillForward.md | 20 ++++ .../SuperLinq/FillForward/FillForward1.linq | 17 ++++ .../SuperLinq/FillForward/FillForward2.linq | 19 ++++ .../SuperLinq/FillForward/FillForward3.linq | 20 ++++ Source/SuperLinq/FillForward.cs | 95 +++++++++++-------- 5 files changed, 132 insertions(+), 39 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FillForward.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FillForward.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FillForward.md new file mode 100644 index 00000000..596aa357 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FillForward.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.FillForward``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to fill in missing elements with previous elements using `FillForward`. +[!code-csharp[](SuperLinq/FillForward/FillForward1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FillForward``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to fill in missing elements with previous elements using `FillForward`. +[!code-csharp[](SuperLinq/FillForward/FillForward2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FillForward``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean},System.Func{``0,``0,``0}) +example: [*content] +--- +The following code example demonstrates how to fill in missing elements with previous elements using `FillForward`. +[!code-csharp[](SuperLinq/FillForward/FillForward3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward1.linq new file mode 100644 index 00000000..f43e2699 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = new int?[] { null, null, 1, 2, null, null, null, 3, 4, null, null, }; + +// Fill in missing elements from previous elements +var result = sequence.FillForward(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [, , 1, 2, 2, 2, 2, 3, 4, 4, 4] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward2.linq new file mode 100644 index 00000000..305eeb28 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward2.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Fill in missing elements from previous elements +var result = sequence + .FillForward( + i => i % 3 < 2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 2, 2, 5, 5, 5, 8, 8, 8] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward3.linq new file mode 100644 index 00000000..d71e6fbf --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward3.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Fill in missing elements from previous elements +var result = sequence + .FillForward( + i => i % 3 < 2, + (cur, nxt) => cur * nxt * 100); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 600, 800, 5, 3000, 3500, 8, 7200, 8000] diff --git a/Source/SuperLinq/FillForward.cs b/Source/SuperLinq/FillForward.cs index 7a7ca6cc..c6bfe92b 100644 --- a/Source/SuperLinq/FillForward.cs +++ b/Source/SuperLinq/FillForward.cs @@ -5,20 +5,24 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Returns a sequence with each null reference or value in the source - /// replaced with the previous non-null reference or value seen in - /// that sequence. + /// Returns a sequence with each null reference or value in the source replaced with the previous non-null + /// reference or value seen in that sequence. /// - /// The source sequence. - /// Type of the elements in the source sequence. + /// + /// The source sequence. + /// + /// + /// Type of the elements in the source sequence. + /// /// - /// An with null references or values - /// replaced. + /// An with null references or values replaced. /// + /// + /// is . + /// /// - /// This method uses deferred execution semantics and streams its - /// results. If references or values are null at the start of the - /// sequence then they remain null. + /// This method uses deferred execution semantics and streams its results. If references or values are at the start of the sequence then they remain . /// public static IEnumerable FillForward(this IEnumerable source) { @@ -26,22 +30,28 @@ public static partial class SuperEnumerable } /// - /// Returns a sequence with each missing element in the source replaced - /// with the previous non-missing element seen in that sequence. An - /// additional parameter specifies a function used to determine if an - /// element is considered missing or not. + /// Returns a sequence with each missing element in the source replaced with the previous non-missing element + /// seen in that sequence. An additional parameter specifies a function used to determine if an element is + /// considered missing or not. /// - /// The source sequence. - /// The function used to determine if - /// an element in the sequence is considered missing. - /// Type of the elements in the source sequence. + /// + /// The source sequence. + /// + /// + /// The function used to determine if an element in the sequence is considered missing. + /// + /// + /// Type of the elements in the source sequence. + /// /// - /// An with missing values replaced. + /// An with missing values replaced. /// + /// + /// or is . + /// /// - /// This method uses deferred execution semantics and streams its - /// results. If elements are missing at the start of the sequence then - /// they remain missing. + /// This method uses deferred execution semantics and streams its results. If elements are missing at the start + /// of the sequence then they remain missing. /// public static IEnumerable FillForward(this IEnumerable source, Func predicate) { @@ -54,27 +64,34 @@ public static IEnumerable FillForward(this IEnumerable source, Func - /// Returns a sequence with each missing element in the source replaced - /// with one based on the previous non-missing element seen in that - /// sequence. Additional parameters specify two functions, one used to - /// determine if an element is considered missing or not and another - /// to provide the replacement for the missing element. + /// Returns a sequence with each missing element in the source replaced with one based on the previous + /// non-missing element seen in that sequence. Additional parameters specify two functions, one used to + /// determine if an element is considered missing or not and another to provide the replacement for the missing + /// element. /// - /// The source sequence. - /// The function used to determine if - /// an element in the sequence is considered missing. - /// The function used to produce the element - /// that will replace the missing one. Its first argument receives the - /// current element considered missing while the second argument - /// receives the previous non-missing element. - /// Type of the elements in the source sequence. + /// + /// The source sequence. + /// + /// + /// The function used to determine if an element in the sequence is considered missing. + /// + /// + /// The function used to produce the element that will replace the missing one. Its first argument receives the + /// current element considered missing while the second argument receives the previous non-missing element. + /// + /// + /// Type of the elements in the source sequence. + /// /// - /// An with missing values replaced. + /// An with missing values replaced. /// + /// + /// , , or is . + /// /// - /// This method uses deferred execution semantics and streams its - /// results. If elements are missing at the start of the sequence then - /// they remain missing. + /// This method uses deferred execution semantics and streams its results. If elements are missing at the start + /// of the sequence then they remain missing. /// public static IEnumerable FillForward(this IEnumerable source, Func predicate, Func fillSelector) { From d4c4b572b3f0872234f4b5d6c4530f04106912f7 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 2 Sep 2023 07:33:56 -0500 Subject: [PATCH 033/124] Update documentation for `Finally` --- .../SuperLinq.SuperEnumerable.Finally.md | 6 +++++ .../apidoc/SuperLinq/Finally/Finally.linq | 16 ++++++++++++ Source/SuperLinq/Finally.cs | 26 ++++++++++++------- 3 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Finally.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Finally/Finally.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Finally.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Finally.md new file mode 100644 index 00000000..4f53f09a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Finally.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Finally``1(System.Collections.Generic.IEnumerable{``0},System.Action) +example: [*content] +--- +The following code example demonstrates how to execute an action when an enumeration completes, using `Finally`. +[!code-csharp[](SuperLinq/Finally/Finally.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Finally/Finally.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Finally/Finally.linq new file mode 100644 index 00000000..a1eead01 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Finally/Finally.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// Execute an action when enumeration is complete, regardless of success or fail. +var result = sequence + .Do(i => Console.Write($"{i}, ")) + .Finally(() => Console.WriteLine("Completed")); + +result.Consume(); + +// This code produces the following output: +// 1, 2, 3, 4, 5, Completed diff --git a/Source/SuperLinq/Finally.cs b/Source/SuperLinq/Finally.cs index fd8ca7d1..c4b3e367 100644 --- a/Source/SuperLinq/Finally.cs +++ b/Source/SuperLinq/Finally.cs @@ -3,18 +3,26 @@ public static partial class SuperEnumerable { /// - /// Creates a sequence whose termination or disposal of an enumerator causes a finally action to be executed. + /// Creates a sequence whose termination or disposal of an enumerator causes a finally action to be executed. /// - /// Source sequence element type. - /// Source sequence. - /// Action to run upon termination of the sequence, or when an enumerator is - /// disposed. - /// Source sequence with guarantees on the invocation of the finally action. - /// or is . + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Action to run upon termination of the sequence, or when an enumerator is disposed. + /// + /// + /// Source sequence with guarantees on the invocation of the finally action. + /// + /// + /// or is . + /// /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// /// public static IEnumerable Finally(this IEnumerable source, Action finallyAction) From 8cd7df229828bf86c133635061d0574261892225 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 2 Sep 2023 10:17:25 -0500 Subject: [PATCH 034/124] Update documentation for `FindIndex` --- .../SuperLinq.SuperEnumerable.FindIndex.md | 20 +++ .../SuperLinq/FindIndex/FindIndex1.linq | 33 +++++ .../SuperLinq/FindIndex/FindIndex2.linq | 32 +++++ .../SuperLinq/FindIndex/FindIndex3.linq | 34 +++++ Source/SuperLinq/FindIndex.cs | 133 +++++++++++------- 5 files changed, 198 insertions(+), 54 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FindIndex.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FindIndex.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FindIndex.md new file mode 100644 index 00000000..040bde1b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FindIndex.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.FindIndex``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to find the index of the first element that satisfies a condition, using `FindIndex`. +[!code-csharp[](SuperLinq/FindIndex/FindIndex1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FindIndex``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean},System.Index) +example: [*content] +--- +The following code example demonstrates how to find the index of the first element that satisfies a condition, using `FindIndex`. +[!code-csharp[](SuperLinq/FindIndex/FindIndex2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FindIndex``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean},System.Index,System.Int32) +example: [*content] +--- +The following code example demonstrates how to find the index of the first element that satisfies a condition, using `FindIndex`. +[!code-csharp[](SuperLinq/FindIndex/FindIndex3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex1.linq new file mode 100644 index 00000000..05d0d9ea --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex1.linq @@ -0,0 +1,33 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 2, name: "Frank"), + (key: 3, name: "Jill"), + (key: 5, name: "Dave"), + (key: 8, name: "Jack"), + (key: 12, name: "Judith"), + (key: 14, name: "Robert"), + (key: 1, name: "Adam"), +}; + +// Find the first index that matches a condition +Console.WriteLine( + "'J' starts at index {0}", + sequence.FindIndex(x => x.name.StartsWith("J"))); + +Console.WriteLine( + "'Ju' starts at index {0}", + sequence.FindIndex(x => x.name.StartsWith("Ju"))); + +Console.WriteLine( + "'K' starts at index {0}", + sequence.FindIndex(x => x.name.StartsWith("K"))); + +// This code produces the following output: +// 'J' starts at index 1 +// 'Ju' starts at index 4 +// 'K' starts at index -1 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex2.linq new file mode 100644 index 00000000..ec0402c9 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex2.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 2, name: "Frank"), + (key: 3, name: "Jill"), + (key: 5, name: "Dave"), + (key: 8, name: "Jack"), + (key: 12, name: "Judith"), + (key: 14, name: "Robert"), + (key: 1, name: "Adam"), +}; + +// Find the first index that matches a condition +Console.WriteLine( + "'J' starts at index {0}, after index 4", + sequence.FindIndex( + x => x.name.StartsWith("J"), + 4)); + +Console.WriteLine( + "'J' starts at index {0}, after index ^2", + sequence.FindIndex( + x => x.name.StartsWith("J"), + ^2)); + +// This code produces the following output: +// 'J' starts at index 4, after index 4 +// 'J' starts at index -1, after index ^2 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex3.linq new file mode 100644 index 00000000..ecc19e59 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex3.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 2, name: "Frank"), + (key: 3, name: "Jill"), + (key: 5, name: "Dave"), + (key: 8, name: "Jack"), + (key: 12, name: "Judith"), + (key: 14, name: "Robert"), + (key: 1, name: "Adam"), +}; + +// Find the first index that matches a condition +Console.WriteLine( + "'J' starts at index {0}, after index 2-4", + sequence.FindIndex( + x => x.name.StartsWith("J"), + 2, + 3)); + +Console.WriteLine( + "'J' starts at index {0}, after index 2-2", + sequence.FindIndex( + x => x.name.StartsWith("J"), + 2, + 1)); + +// This code produces the following output: +// 'J' starts at index 3, after index 2-4 +// 'J' starts at index -1, after index 2-2 diff --git a/Source/SuperLinq/FindIndex.cs b/Source/SuperLinq/FindIndex.cs index ec302bef..f366c44b 100644 --- a/Source/SuperLinq/FindIndex.cs +++ b/Source/SuperLinq/FindIndex.cs @@ -3,31 +3,37 @@ public static partial class SuperEnumerable { /// - /// Searches for an element that matches the conditions defined by the specified predicate and returns the - /// zero-based index of the first occurrence within the entire . + /// Searches for an element that matches the conditions defined by the specified predicate and returns the + /// zero-based index of the first occurrence within the entire . /// /// - /// The type of elements of - /// The source sequence. - /// The predicate that defines the conditions of the element to search for. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The predicate that defines the conditions of the element to search for. + /// /// - /// The zero-based index of the first occurrence of an element that matches the conditions defined by within the entire , if found; otherwise, -1. + /// The zero-based index of the first occurrence of an element that matches the conditions defined by within the entire , if found; otherwise, -1. /// - /// or is - /// null. + /// + /// or is . + /// /// /// - /// The is searched forward starting at the first element and ending at the last - /// element. + /// The is searched forward starting at the first element and ending at the last + /// element. /// /// - /// The is a delegate to a method that returns if the object - /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. + /// The is a delegate to a method that returns if the object + /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int FindIndex(this IEnumerable source, Func predicate) @@ -36,34 +42,42 @@ public static int FindIndex(this IEnumerable source, Func - /// Searches for an element that matches the conditions defined by the specified predicate and returns the - /// zero-based index of the first occurrence within the range of elements in the that - /// extends from the specified index to the last element. + /// Searches for an element that matches the conditions defined by the specified predicate and returns the + /// zero-based index of the first occurrence within the range of elements in the + /// that extends from the specified index to the last element. /// /// - /// The type of elements of - /// The source sequence. - /// The predicate that defines the conditions of the element to search for. - /// The of the starting element within the sequence. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The predicate that defines the conditions of the element to search for. + /// + /// + /// The of the starting element within the sequence. + /// /// - /// The zero-based index of the first occurrence of an element that matches the conditions defined by within the the range of elements in the that extends from - /// to the last element, if found; otherwise, -1. + /// The zero-based index of the first occurrence of an element that matches the conditions defined by within the the range of elements in the that extends from + /// to the last element, if found; otherwise, -1. /// - /// or is - /// null. + /// + /// or is . + /// /// /// - /// The is searched forward starting at and ending at the last - /// element. + /// The is searched forward starting at and ending at the + /// last element. /// /// - /// The is a delegate to a method that returns if the object - /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. + /// The is a delegate to a method that returns if the object + /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int FindIndex(this IEnumerable source, Func predicate, Index index) @@ -72,37 +86,48 @@ public static int FindIndex(this IEnumerable source, Func - /// Searches for an element that matches the conditions defined by the specified predicate and returns the - /// zero-based index of the first occurrence within the range of elements in the that - /// starts at the specified index to the last element and contains the specified number of elements. + /// Searches for an element that matches the conditions defined by the specified predicate and returns the + /// zero-based index of the first occurrence within the range of elements in the + /// that starts at the specified index to the last element and contains the specified number of elements. /// /// - /// The type of elements of - /// The source sequence. - /// The predicate that defines the conditions of the element to search for. - /// The of the starting element within the sequence. - /// The number of elements in the section to search. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// The predicate that defines the conditions of the element to search for. + /// + /// + /// The of the starting element within the sequence. + /// + /// + /// The number of elements in the section to search. + /// /// - /// The zero-based index of the first occurrence of an element that matches the conditions defined by within the the range of elements in the that that starts at - /// and contains number of elements, if found; otherwise, - /// -1. + /// The zero-based index of the first occurrence of an element that matches the conditions defined by within the the range of elements in the that that starts at + /// and contains number of elements, if found; otherwise, + /// -1. /// - /// or is - /// null. - /// is less than 0. + /// + /// or is . + /// + /// + /// is less than 0. + /// /// /// - /// The is searched forward starting at and ending at - /// plus minus 1, if count is greater than 0. + /// The is searched forward starting at and ending at + /// plus minus 1, if count is greater than 0. /// /// - /// The is a delegate to a method that returns if the object - /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. + /// The is a delegate to a method that returns if the object + /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int FindIndex(this IEnumerable source, Func predicate, Index index, int count) From 54a33b67339eb22a2740bcd58b501095c0ce5050 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sun, 3 Sep 2023 17:32:06 -0500 Subject: [PATCH 035/124] Update documentation for `FindLastIndex` --- ...SuperLinq.SuperEnumerable.FindLastIndex.md | 20 +++ .../FindLastIndex/FindLastIndex1.linq | 36 +++++ .../FindLastIndex/FindLastIndex2.linq | 32 ++++ .../FindLastIndex/FindLastIndex3.linq | 33 ++++ Source/SuperLinq/FindLastIndex.cs | 142 +++++++++++------- 5 files changed, 205 insertions(+), 58 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FindLastIndex.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FindLastIndex.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FindLastIndex.md new file mode 100644 index 00000000..71e2bd01 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FindLastIndex.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.FindLastIndex``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to find the index of the last element that satisfies a condition, using `FindLastIndex`. +[!code-csharp[](SuperLinq/FindLastIndex/FindLastIndex1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FindLastIndex``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean},System.Index) +example: [*content] +--- +The following code example demonstrates how to find the index of the last element that satisfies a condition, using `FindLastIndex`. +[!code-csharp[](SuperLinq/FindLastIndex/FindLastIndex2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FindLastIndex``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean},System.Index,System.Int32) +example: [*content] +--- +The following code example demonstrates how to find the index of the last element that satisfies a condition, using `FindLastIndex`. +[!code-csharp[](SuperLinq/FindLastIndex/FindLastIndex3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex1.linq new file mode 100644 index 00000000..ea6dbda6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex1.linq @@ -0,0 +1,36 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 2, name: "Frank"), + (key: 3, name: "Jill"), + (key: 5, name: "Dave"), + (key: 8, name: "Jack"), + (key: 12, name: "Judith"), + (key: 14, name: "Robert"), + (key: 1, name: "Adam"), +}; + +// Find the first index that matches a condition +Console.WriteLine( + "'J' starts at index {0}", + sequence.FindLastIndex( + x => x.name.StartsWith("J"))); + +Console.WriteLine( + "'Ji' starts at index {0}", + sequence.FindLastIndex( + x => x.name.StartsWith("Ji"))); + +Console.WriteLine( + "'K' starts at index {0}", + sequence.FindLastIndex( + x => x.name.StartsWith("K"))); + +// This code produces the following output: +// 'J' starts at index 4 +// 'Ji' starts at index 1 +// 'K' starts at index -1 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex2.linq new file mode 100644 index 00000000..0a705c41 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex2.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 2, name: "Frank"), + (key: 3, name: "Jill"), + (key: 5, name: "Dave"), + (key: 8, name: "Jack"), + (key: 12, name: "Judith"), + (key: 14, name: "Robert"), + (key: 1, name: "Adam"), +}; + +// Find the first index that matches a condition +Console.WriteLine( + "'J' starts at index {0}, before index 0", + sequence.FindLastIndex( + x => x.name.StartsWith("J"), + 0)); + +Console.WriteLine( + "'J' starts at index {0}, before index ^2", + sequence.FindLastIndex( + x => x.name.StartsWith("J"), + ^2)); + +// This code produces the following output: +// 'J' starts at index -1, before index 0 +// 'J' starts at index 4, before index ^2 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex3.linq new file mode 100644 index 00000000..8c1e23e3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex3.linq @@ -0,0 +1,33 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 2, name: "Frank"), + (key: 3, name: "Jill"), + (key: 5, name: "Dave"), + (key: 8, name: "Jack"), + (key: 12, name: "Judith"), + (key: 14, name: "Robert"), + (key: 1, name: "Adam"), +}; + +// Find the first index that matches a condition +Console.WriteLine( + "'J' starts at index {0}, before index 0", + sequence.FindLastIndex( + x => x.name.StartsWith("J"), + 1, + 1)); + +Console.WriteLine( + "'J' starts at index {0}, before index ^2", + sequence.FindLastIndex( + x => x.name.StartsWith("J"), + ^2)); + +// This code produces the following output: +// 'J' starts at index -1, before index 0 +// 'J' starts at index 4, before index ^2 diff --git a/Source/SuperLinq/FindLastIndex.cs b/Source/SuperLinq/FindLastIndex.cs index 2e5b8788..c16adda5 100644 --- a/Source/SuperLinq/FindLastIndex.cs +++ b/Source/SuperLinq/FindLastIndex.cs @@ -3,32 +3,38 @@ public static partial class SuperEnumerable { /// - /// Searches for an element that matches the conditions defined by the specified predicate and returns the - /// zero-based index of the last occurrence within the entire . + /// Searches for an element that matches the conditions defined by the specified predicate and returns the + /// zero-based index of the last occurrence within the entire . /// /// - /// The type of elements of - /// The source sequence. - /// The predicate that defines the conditions of the element to search for. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The predicate that defines the conditions of the element to search for. + /// /// - /// The zero-based index of the last occurrence of an element that matches the conditions defined by within the entire , if found; otherwise, -1. + /// The zero-based index of the last occurrence of an element that matches the conditions defined by within the entire , if found; otherwise, -1. /// - /// or is - /// null. + /// + /// or is . + /// /// /// - /// The is searched forward starting at the first element and ending at the last - /// element, and the index of the last instance of an element that matches the conditions defined by is returned. + /// The is searched forward starting at the first element and ending at the last + /// element, and the index of the last instance of an element that matches the conditions defined by is returned. /// /// - /// The is a delegate to a method that returns if the object - /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. + /// The is a delegate to a method that returns if the object + /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int FindLastIndex(this IEnumerable source, Func predicate) @@ -37,35 +43,43 @@ public static int FindLastIndex(this IEnumerable source, Func< } /// - /// Searches for an element that matches the conditions defined by the specified predicate and returns the - /// zero-based index of the last occurrence within the range of elements in the that - /// extends backwards from the specified index to the first element. + /// Searches for an element that matches the conditions defined by the specified predicate and returns the + /// zero-based index of the last occurrence within the range of elements in the + /// that extends backwards from the specified index to the first element. /// /// - /// The type of elements of - /// The source sequence. - /// The predicate that defines the conditions of the element to search for. - /// The of the ending element within the sequence. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The predicate that defines the conditions of the element to search for. + /// + /// + /// The of the ending element within the sequence. + /// /// - /// The zero-based index of the last occurrence of an element that matches the conditions defined by within the the range of elements in the that extends backwards - /// from to the first element, if found; otherwise, -1. + /// The zero-based index of the last occurrence of an element that matches the conditions defined by within the the range of elements in the that extends + /// backwards from to the first element, if found; otherwise, -1. /// - /// or is - /// null. + /// + /// or is . + /// /// /// - /// The is searched forward starting at the first element and ending at , and the index of the last instance of an element that matches the conditions defined by - /// is returned. + /// The is searched forward starting at the first element and ending at , and the index of the last instance of an element that matches the conditions defined by + /// is returned. /// /// - /// The is a delegate to a method that returns if the object - /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. + /// The is a delegate to a method that returns if the object + /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int FindLastIndex(this IEnumerable source, Func predicate, Index index) @@ -74,39 +88,51 @@ public static int FindLastIndex(this IEnumerable source, Func< } /// - /// Searches for an element that matches the conditions defined by the specified predicate and returns the - /// zero-based index of the last occurrence within the range of elements in the that - /// ends at the specified index to the last element and contains the specified number of elements. + /// Searches for an element that matches the conditions defined by the specified predicate and returns the + /// zero-based index of the last occurrence within the range of elements in the + /// that ends at the specified index to the last element and contains the specified number of elements. /// /// - /// The type of elements of - /// The source sequence. - /// The predicate that defines the conditions of the element to search for. - /// The of the ending element within the sequence. - /// The number of elements in the section to search. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The predicate that defines the conditions of the element to search for. + /// + /// + /// The of the ending element within the sequence. + /// + /// + /// The number of elements in the section to search. + /// /// - /// The zero-based index of the last occurrence of an element that matches the conditions defined by within the the range of elements in the that that ends at - /// and contains number of elements, if found; otherwise, - /// -1. + /// The zero-based index of the last occurrence of an element that matches the conditions defined by within the the range of elements in the that that ends at + /// and contains number of elements, if found; otherwise, + /// -1. /// - /// or is - /// null. - /// is less than 0. + /// + /// or is . + /// + /// + /// is less than 0. + /// /// /// - /// The is searched forward starting at the first element and ending at , and the index of the last instance of an element that matches the conditions defined by - /// no earlier in the sequence than items before is returned. + /// The is searched forward starting at the first element and ending at , and the index of the last instance of an element that matches the conditions defined by + /// no earlier in the sequence than items before is returned. /// /// - /// The is a delegate to a method that returns if the object - /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. + /// The is a delegate to a method that returns if the object + /// passed to it matches the conditions defined in the delegate. The elements of the current are individually passed to the delegate. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int FindLastIndex(this IEnumerable source, Func predicate, Index index, int count) From 1be2d80102999fe1683812e091310046c9f52e7a Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 4 Sep 2023 07:09:35 -0500 Subject: [PATCH 036/124] Update documentation for `Flatten` --- .../SuperLinq.SuperEnumerable.Flatten.md | 20 +++++ .../apidoc/SuperLinq/Flatten/Flatten1.linq | 34 ++++++++ .../apidoc/SuperLinq/Flatten/Flatten2.linq | 34 ++++++++ .../apidoc/SuperLinq/Flatten/Flatten3.linq | 40 +++++++++ Source/SuperLinq/Flatten.cs | 81 ++++++++++--------- 5 files changed, 171 insertions(+), 38 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Flatten.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Flatten.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Flatten.md new file mode 100644 index 00000000..ac4f09e2 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Flatten.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.Flatten(System.Collections.IEnumerable) +example: [*content] +--- +The following code example demonstrates how to flatten hierarchical sequences into a flat sequences using `Flatten`. +[!code-csharp[](SuperLinq/Flatten/Flatten1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Flatten(System.Collections.IEnumerable,System.Func{System.Collections.IEnumerable,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to flatten hierarchical sequences into a flat sequences using `Flatten`. +[!code-csharp[](SuperLinq/Flatten/Flatten2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Flatten(System.Collections.IEnumerable,System.Func{System.Object,System.Collections.IEnumerable}) +example: [*content] +--- +The following code example demonstrates how to flatten hierarchical sequences into a flat sequences using `Flatten`. +[!code-csharp[](SuperLinq/Flatten/Flatten3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten1.linq new file mode 100644 index 00000000..8dc30142 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten1.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var sequence = new object[] +{ + 1, 2, 3, + new object[] + { + 4, 5, + new object[] { 6, 7, }, + 8, 9, 10, + }, + 11, + new object[] + { + 12, 13, 14, + new object[] { 15, 16, 17, }, + 18, 19, + }, + 20, +}; + +// Flatten a hierarchical sequence +var result = sequence.Flatten(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten2.linq new file mode 100644 index 00000000..690860d3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten2.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var sequence = new object[] +{ + 1, 2, 3, + new object[] + { + 4, 5, + new int[] { 6, 7, 8, }, + }, + 9, 10, 11, + new object[] + { + 12, 13, 14, + new object[] { 15, 16, 17, }, + 18, 19, + }, + 20, +}; + +// Flatten a hierarchical sequence +var result = sequence + .Flatten(e => e is not int[]); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4, 5, System.Int32[], 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten3.linq new file mode 100644 index 00000000..ab823bd8 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten3.linq @@ -0,0 +1,40 @@ + + SuperLinq + SuperLinq + + +var sequence = new object[] +{ + true, + false, + 1, + "bar", + new object[] + { + 2, + new[] + { + 3, + }, + }, + 'c', + 4, +}; + +// Flatten a hierarchical sequence +var result = sequence + .Flatten(obj => + obj switch + { + int => null, + IEnumerable inner => inner, + _ => Enumerable.Empty(), + }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4] diff --git a/Source/SuperLinq/Flatten.cs b/Source/SuperLinq/Flatten.cs index a90057bb..af750a62 100644 --- a/Source/SuperLinq/Flatten.cs +++ b/Source/SuperLinq/Flatten.cs @@ -5,40 +5,44 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Flattens a sequence containing arbitrarily-nested sequences. + /// Flattens a sequence containing arbitrarily-nested sequences. /// - /// The sequence that will be flattened. + /// + /// The sequence that will be flattened. + /// /// - /// A sequence that contains the elements of - /// and all nested sequences (except strings). + /// A sequence that contains the elements of and all nested sequences (except + /// strings). /// - /// is . - + /// + /// is . + /// + /// + /// This method uses deferred execution and streams its results. + /// public static IEnumerable Flatten(this IEnumerable source) => Flatten(source, obj => obj is not string); /// - /// Flattens a sequence containing arbitrarily-nested sequences. An - /// additional parameter specifies a predicate function used to - /// determine whether a nested should be - /// flattened or not. + /// Flattens a sequence containing arbitrarily-nested sequences. An additional parameter specifies a predicate + /// function used to determine whether a nested should be flattened or not. /// - /// The sequence that will be flattened. + /// + /// The sequence that will be flattened. /// - /// A function that receives each element that implements - /// and indicates if its elements should be - /// recursively flattened into the resulting sequence. + /// A function that receives each element that implements and indicates if its + /// elements should be recursively flattened into the resulting sequence. /// /// - /// A sequence that contains the elements of - /// and all nested sequences for which the predicate function - /// returned . + /// A sequence that contains the elements of and all nested sequences for which the + /// predicate function returned . /// /// - /// is . - /// - /// is . - + /// or is . + /// + /// + /// This method uses deferred execution and streams its results. + /// public static IEnumerable Flatten(this IEnumerable source, Func predicate) { Guard.IsNotNull(predicate); @@ -47,33 +51,35 @@ public static partial class SuperEnumerable } /// - /// Flattens a sequence containing arbitrarily-nested sequences. An - /// additional parameter specifies a function that projects an inner - /// sequence via a property of an object. + /// Flattens a sequence containing arbitrarily-nested sequences. An additional parameter specifies a function + /// that projects an inner sequence via a property of an object. /// - /// The sequence that will be flattened. + /// + /// The sequence that will be flattened. + /// /// - /// A function that receives each element of the sequence as an object - /// and projects an inner sequence to be flattened. If the function - /// returns then the object argument is considered a leaf - /// of the flattening process. + /// A function that receives each element of the sequence as an object and projects an inner sequence to be + /// flattened. If the function returns then the object argument is considered a leaf of + /// the flattening process. /// /// - /// A sequence that contains the elements of - /// and all nested sequences projected via the - /// function. + /// A sequence that contains the elements of and all nested sequences projected via + /// the function. /// /// - /// is . - /// - /// is . - + /// or is . + /// + /// + /// This method uses deferred execution and streams its results. + /// public static IEnumerable Flatten(this IEnumerable source, Func selector) { Guard.IsNotNull(source); Guard.IsNotNull(selector); - return Core(); IEnumerable Core() + return Core(source, selector); + + static IEnumerable Core(IEnumerable source, Func selector) { var e = source.GetEnumerator(); var stack = new Stack(); @@ -87,7 +93,6 @@ public static partial class SuperEnumerable e = stack.Pop(); reloop: - while (e.MoveNext()) { if (selector(e.Current) is { } inner) From a02f7b8d87cd38ad8830a125a4ea357ff8c05b86 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 4 Sep 2023 10:08:43 -0500 Subject: [PATCH 037/124] Update documentation for `Fold` --- .../apidoc/SuperLinq.SuperEnumerable.Fold.md | 112 ++++ .../apidoc/SuperLinq/Fold/Fold1.linq | 15 + .../apidoc/SuperLinq/Fold/Fold10.linq | 16 + .../apidoc/SuperLinq/Fold/Fold11.linq | 16 + .../apidoc/SuperLinq/Fold/Fold12.linq | 16 + .../apidoc/SuperLinq/Fold/Fold13.linq | 16 + .../apidoc/SuperLinq/Fold/Fold14.linq | 16 + .../apidoc/SuperLinq/Fold/Fold15.linq | 16 + .../apidoc/SuperLinq/Fold/Fold16.linq | 16 + .../apidoc/SuperLinq/Fold/Fold2.linq | 15 + .../apidoc/SuperLinq/Fold/Fold3.linq | 15 + .../apidoc/SuperLinq/Fold/Fold4.linq | 15 + .../apidoc/SuperLinq/Fold/Fold5.linq | 15 + .../apidoc/SuperLinq/Fold/Fold6.linq | 15 + .../apidoc/SuperLinq/Fold/Fold7.linq | 16 + .../apidoc/SuperLinq/Fold/Fold8.linq | 16 + .../apidoc/SuperLinq/Fold/Fold9.linq | 16 + Generators/SuperLinq.Generator/Fold.sbntxt | 30 +- .../SuperLinq.Generator.Generator/Fold.g.cs | 480 ++++++++++++------ 19 files changed, 719 insertions(+), 153 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Fold.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold10.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold11.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold12.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold13.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold14.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold15.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold16.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold5.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold6.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold7.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold8.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold9.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Fold.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Fold.md new file mode 100644 index 00000000..ae97f606 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Fold.md @@ -0,0 +1,112 @@ +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 1 element using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 2 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 3 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 4 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 5 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold5.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 6 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold6.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 7 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold7.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 8 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold8.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 9 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold9.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 10 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold10.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 11 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold11.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 12 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold12.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 13 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold13.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 14 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold14.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 15 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold15.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Fold``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to apply a projection to a sequence of 16 elements using `Fold`. +[!code-csharp[](SuperLinq/Fold/Fold16.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold1.linq new file mode 100644 index 00000000..9667cfb0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold1.linq @@ -0,0 +1,15 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 1); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a) => a); + +Console.WriteLine(result); + +// This code produces the following output: +// 1 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold10.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold10.linq new file mode 100644 index 00000000..1128a9ae --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold10.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e, f, g, h, i, j) => + a + b + c + d + e + f + g + h + i + j); + +Console.WriteLine(result); + +// This code produces the following output: +// 55 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold11.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold11.linq new file mode 100644 index 00000000..32ff7d63 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold11.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 11); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e, f, g, h, i, j, k) => + a + b + c + d + e + f + g + h + i + j + k); + +Console.WriteLine(result); + +// This code produces the following output: +// 66 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold12.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold12.linq new file mode 100644 index 00000000..98f50c68 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold12.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 12); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e, f, g, h, i, j, k, l) => + a + b + c + d + e + f + g + h + i + j + k + l); + +Console.WriteLine(result); + +// This code produces the following output: +// 78 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold13.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold13.linq new file mode 100644 index 00000000..f6b8ed59 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold13.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 13); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e, f, g, h, i, j, k, l, m) => + a + b + c + d + e + f + g + h + i + j + k + l + m); + +Console.WriteLine(result); + +// This code produces the following output: +// 91 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold14.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold14.linq new file mode 100644 index 00000000..b8ae6e34 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold14.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 14); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e, f, g, h, i, j, k, l, m, n) => + a + b + c + d + e + f + g + h + i + j + k + l + m + n); + +Console.WriteLine(result); + +// This code produces the following output: +// 105 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold15.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold15.linq new file mode 100644 index 00000000..88485c56 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold15.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 15); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) => + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o); + +Console.WriteLine(result); + +// This code produces the following output: +// 120 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold16.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold16.linq new file mode 100644 index 00000000..4237bd17 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold16.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 16); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p); + +Console.WriteLine(result); + +// This code produces the following output: +// 136 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold2.linq new file mode 100644 index 00000000..1bb4c3b9 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold2.linq @@ -0,0 +1,15 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 2); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b) => a + b); + +Console.WriteLine(result); + +// This code produces the following output: +// 3 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold3.linq new file mode 100644 index 00000000..6e3f671c --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold3.linq @@ -0,0 +1,15 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 3); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c) => a + b + c); + +Console.WriteLine(result); + +// This code produces the following output: +// 6 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold4.linq new file mode 100644 index 00000000..e40ec88f --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold4.linq @@ -0,0 +1,15 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 4); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d) => a + b + c + d); + +Console.WriteLine(result); + +// This code produces the following output: +// 10 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold5.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold5.linq new file mode 100644 index 00000000..e8d4d9c1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold5.linq @@ -0,0 +1,15 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e) => a + b + c + d + e); + +Console.WriteLine(result); + +// This code produces the following output: +// 15 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold6.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold6.linq new file mode 100644 index 00000000..61fc9fb8 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold6.linq @@ -0,0 +1,15 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 6); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e, f) => a + b + c + d + e + f); + +Console.WriteLine(result); + +// This code produces the following output: +// 21 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold7.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold7.linq new file mode 100644 index 00000000..b2a4d41e --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold7.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 7); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e, f, g) => + a + b + c + d + e + f + g); + +Console.WriteLine(result); + +// This code produces the following output: +// 28 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold8.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold8.linq new file mode 100644 index 00000000..0ff67cd1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold8.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 8); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e, f, g, h) => + a + b + c + d + e + f + g + h); + +Console.WriteLine(result); + +// This code produces the following output: +// 36 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold9.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold9.linq new file mode 100644 index 00000000..1d45fb6e --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Fold/Fold9.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 9); + +// Fold a sequence into a single value. +var result = sequence + .Fold((a, b, c, d, e, f, g, h, i) => + a + b + c + d + e + f + g + h + i); + +Console.WriteLine(result); + +// This code produces the following output: +// 45 diff --git a/Generators/SuperLinq.Generator/Fold.sbntxt b/Generators/SuperLinq.Generator/Fold.sbntxt index fdc4da57..db2a46c4 100644 --- a/Generators/SuperLinq.Generator/Fold.sbntxt +++ b/Generators/SuperLinq.Generator/Fold.sbntxt @@ -6,19 +6,31 @@ public static partial class SuperEnumerable { {{~ for $i in 1..16 ~}} /// - /// Returns the result of applying a function to a sequence of {{$i}} element{{if $i != 1}}s{{end}}. + /// Returns the result of applying a function to a sequence of {{$i}} element{{if $i != 1}}s{{end}}. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly {{$i}} element{{if $i != 1}}s{{end}}. + /// does not contain exactly {{$i}} element{{if $i != 1}}s{{end}}. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func< {{~ for $j in 1..$i ~}} diff --git a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/Fold.g.cs b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/Fold.g.cs index 7ed84307..56f00dbd 100644 --- a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/Fold.g.cs +++ b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/Fold.g.cs @@ -3,19 +3,31 @@ public static partial class SuperEnumerable { /// - /// Returns the result of applying a function to a sequence of 1 element. + /// Returns the result of applying a function to a sequence of 1 element. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 1 element. + /// does not contain exactly 1 element. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -26,19 +38,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 2 elements. + /// Returns the result of applying a function to a sequence of 2 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 2 elements. + /// does not contain exactly 2 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -49,19 +73,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 3 elements. + /// Returns the result of applying a function to a sequence of 3 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 3 elements. + /// does not contain exactly 3 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -72,19 +108,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 4 elements. + /// Returns the result of applying a function to a sequence of 4 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 4 elements. + /// does not contain exactly 4 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -95,19 +143,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 5 elements. + /// Returns the result of applying a function to a sequence of 5 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 5 elements. + /// does not contain exactly 5 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -118,19 +178,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 6 elements. + /// Returns the result of applying a function to a sequence of 6 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 6 elements. + /// does not contain exactly 6 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -141,19 +213,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 7 elements. + /// Returns the result of applying a function to a sequence of 7 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 7 elements. + /// does not contain exactly 7 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -164,19 +248,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 8 elements. + /// Returns the result of applying a function to a sequence of 8 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 8 elements. + /// does not contain exactly 8 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -187,19 +283,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 9 elements. + /// Returns the result of applying a function to a sequence of 9 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 9 elements. + /// does not contain exactly 9 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -210,19 +318,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 10 elements. + /// Returns the result of applying a function to a sequence of 10 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 10 elements. + /// does not contain exactly 10 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -233,19 +353,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 11 elements. + /// Returns the result of applying a function to a sequence of 11 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 11 elements. + /// does not contain exactly 11 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -256,19 +388,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 12 elements. + /// Returns the result of applying a function to a sequence of 12 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 12 elements. + /// does not contain exactly 12 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -279,19 +423,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 13 elements. + /// Returns the result of applying a function to a sequence of 13 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 13 elements. + /// does not contain exactly 13 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -302,19 +458,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 14 elements. + /// Returns the result of applying a function to a sequence of 14 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 14 elements. + /// does not contain exactly 14 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -325,19 +493,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 15 elements. + /// Returns the result of applying a function to a sequence of 15 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 15 elements. + /// does not contain exactly 15 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { @@ -348,19 +528,31 @@ public static TResult Fold(this global::System.Collections.Generic.I } /// - /// Returns the result of applying a function to a sequence of 16 elements. + /// Returns the result of applying a function to a sequence of 16 elements. /// /// - /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. + /// This operator uses immediate execution and buffers as many items of the source sequence as necessary. /// - /// Type of element in the source sequence - /// Type of the result - /// The sequence of items to fold. - /// Function to apply to the elements in the sequence. - /// The folded value returned by . - /// or is null. + /// + /// Type of element in the source sequence + /// + /// + /// Type of the result + /// + /// + /// The sequence of items to fold. + /// + /// + /// Function to apply to the elements in the sequence. + /// + /// + /// The folded value returned by . + /// + /// + /// or is . + /// /// - /// does not contain exactly 16 elements. + /// does not contain exactly 16 elements. /// public static TResult Fold(this global::System.Collections.Generic.IEnumerable source, global::System.Func folder) { From 95d668758677f2ad71cab0c949f8a49d695965ac Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 4 Sep 2023 10:08:56 -0500 Subject: [PATCH 038/124] Update documentation for `ForEach` --- .../SuperLinq.SuperEnumerable.ForEach.md | 13 ++++++ .../apidoc/SuperLinq/ForEach/ForEach1.linq | 13 ++++++ .../apidoc/SuperLinq/ForEach/ForEach2.linq | 13 ++++++ Source/SuperLinq/ForEach.cs | 46 ++++++++++++------- 4 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ForEach.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ForEach/ForEach1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ForEach/ForEach2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ForEach.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ForEach.md new file mode 100644 index 00000000..60029999 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ForEach.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.ForEach``1(System.Collections.Generic.IEnumerable{``0},System.Action{``0}) +example: [*content] +--- +The following code example demonstrates how to immediately execute an action on every element of a sequence using `ForEach`. +[!code-csharp[](SuperLinq/ForEach/ForEach1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ForEach``1(System.Collections.Generic.IEnumerable{``0},System.Action{``0,System.Int32}) +example: [*content] +--- +The following code example demonstrates how to immediately execute an action on every element of a sequence using `ForEach`. +[!code-csharp[](SuperLinq/ForEach/ForEach2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ForEach/ForEach1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ForEach/ForEach1.linq new file mode 100644 index 00000000..935f4c09 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ForEach/ForEach1.linq @@ -0,0 +1,13 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// Fold a sequence into a single value. +sequence + .ForEach(x => Console.Write($"{x}, ")); + +// This code produces the following output: +// 1, 2, 3, 4, 5, diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ForEach/ForEach2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ForEach/ForEach2.linq new file mode 100644 index 00000000..ed5f638b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ForEach/ForEach2.linq @@ -0,0 +1,13 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// Fold a sequence into a single value. +sequence + .ForEach((x, i) => Console.Write($"({x}, {i}), ")); + +// This code produces the following output: +// (1, 0), (2, 1), (3, 2), (4, 3), (5, 4), diff --git a/Source/SuperLinq/ForEach.cs b/Source/SuperLinq/ForEach.cs index fe1d7d45..1e1264d9 100644 --- a/Source/SuperLinq/ForEach.cs +++ b/Source/SuperLinq/ForEach.cs @@ -3,15 +3,22 @@ public partial class SuperEnumerable { /// - /// Immediately executes the given action on each element in the source sequence. + /// Immediately executes the given action on each element in the source sequence. /// - /// The type of the elements in the sequence - /// The sequence of elements - /// The action to execute on each element - /// or is . + /// + /// The type of the elements in the sequence + /// + /// + /// The sequence of elements + /// + /// + /// The action to execute on each element + /// + /// + /// or is . + /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// public static void ForEach(this IEnumerable source, Action action) { @@ -23,17 +30,24 @@ public static void ForEach(this IEnumerable source, Action - /// Immediately executes the given action on each element in the source sequence. Each element's index is used in - /// the logic of the action. + /// Immediately executes the given action on each element in the source sequence. Each element's index is used + /// in the logic of the action. /// - /// The type of the elements in the sequence - /// The sequence of elements - /// The action to execute on each element; the second parameter of the action represents the - /// index of the source element. - /// or is . + /// + /// The type of the elements in the sequence + /// + /// + /// The sequence of elements + /// + /// + /// The action to execute on each element; the second parameter of the action represents the index of the source + /// element. + /// + /// + /// or is . + /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// public static void ForEach(this IEnumerable source, Action action) { From ebe093b3119e98dd8aad9029bacfd710ada237d7 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 6 Sep 2023 09:34:07 -0500 Subject: [PATCH 039/124] Update documentation for `From` --- .../apidoc/SuperLinq.SuperEnumerable.From.md | 27 +++++ .../apidoc/SuperLinq/From/From1.linq | 18 +++ .../apidoc/SuperLinq/From/From2.linq | 19 +++ .../apidoc/SuperLinq/From/From3.linq | 20 ++++ .../apidoc/SuperLinq/From/From4.linq | 21 ++++ Source/SuperLinq/From.cs | 109 ++++++++++++------ 6 files changed, 178 insertions(+), 36 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.From.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.From.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.From.md new file mode 100644 index 00000000..379bf2ee --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.From.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.From``1(System.Func{``0}) +example: [*content] +--- +The following code example demonstrates how to project a sequence of functions into their return values using `From`. +[!code-csharp[](SuperLinq/From/From1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.From``1(System.Func{``0},System.Func{``0}) +example: [*content] +--- +The following code example demonstrates how to project a sequence of functions into their return values using `From`. +[!code-csharp[](SuperLinq/From/From2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.From``1(System.Func{``0},System.Func{``0},System.Func{``0}) +example: [*content] +--- +The following code example demonstrates how to project a sequence of functions into their return values using `From`. +[!code-csharp[](SuperLinq/From/From3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.From``1(System.Func{``0}[]) +example: [*content] +--- +The following code example demonstrates how to project a sequence of functions into their return values using `From`. +[!code-csharp[](SuperLinq/From/From4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From1.linq new file mode 100644 index 00000000..49f71733 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +int Func1() => 3; + +// Execute an action for each element +var result = SuperEnumerable + .From(Func1); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [3] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From2.linq new file mode 100644 index 00000000..eeeb87be --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From2.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +int Func1() => 3; +int Func2() => 5; + +// Execute an action for each element +var result = SuperEnumerable + .From(Func1, Func2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [3, 5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From3.linq new file mode 100644 index 00000000..5861dbb6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From3.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +int Func1() => 3; +int Func2() => 5; +int Func3() => 1; + +// Execute an action for each element +var result = SuperEnumerable + .From(Func1, Func2, Func3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [3, 5, 1] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From4.linq new file mode 100644 index 00000000..8e32764b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/From/From4.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +int Func1() => 3; +int Func2() => 5; +int Func3() => 1; +int Func4() => 7; + +// Execute an action for each element +var result = SuperEnumerable + .From(Func1, Func2, Func3, Func4); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [3, 5, 1, 7] diff --git a/Source/SuperLinq/From.cs b/Source/SuperLinq/From.cs index 2242cf7a..35a9e52c 100644 --- a/Source/SuperLinq/From.cs +++ b/Source/SuperLinq/From.cs @@ -3,17 +3,24 @@ public partial class SuperEnumerable { /// - /// Returns a single-element sequence containing the result of invoking the function. + /// Returns a single-element sequence containing the result of invoking the function. /// + /// + /// The type of the object returned by the function. + /// + /// + /// The function to evaluate. + /// + /// + /// A sequence with the value resulting from invoking . + /// + /// + /// is . + /// /// - /// This operator uses deferred execution and streams the results. - /// If the resulting sequence is enumerated multiple times, the function will be - /// invoked multiple times too. + /// This operator uses deferred execution and streams the results. If the resulting sequence is enumerated + /// multiple times, the function will be invoked multiple times too. /// - /// The type of the object returned by the function. - /// The function to evaluate. - /// A sequence with the value resulting from invoking . - public static IEnumerable From(Func function) { Guard.IsNotNull(function); @@ -26,18 +33,28 @@ static IEnumerable Core(Func function) } /// - /// Returns a sequence containing the result of invoking each parameter function in order. + /// Returns a sequence containing the result of invoking each parameter function in order. /// + /// + /// The type of the object returned by the functions. + /// + /// + /// The first function to evaluate. + /// + /// + /// The second function to evaluate. + /// + /// + /// A sequence with the values resulting from invoking and . + /// + /// + /// or is . + /// /// - /// This operator uses deferred execution and streams the results. - /// If the resulting sequence is enumerated multiple times, the functions will be - /// invoked multiple times too. + /// This operator uses deferred execution and streams the results. If the resulting sequence is enumerated + /// multiple times, the functions will be invoked multiple times too. /// - /// The type of the object returned by the functions. - /// The first function to evaluate. - /// The second function to evaluate. - /// A sequence with the values resulting from invoking and . - public static IEnumerable From(Func function1, Func function2) { Guard.IsNotNull(function1); @@ -52,19 +69,32 @@ static IEnumerable Core(Func function1, Func function2) } /// - /// Returns a sequence containing the result of invoking each parameter function in order. + /// Returns a sequence containing the result of invoking each parameter function in order. /// + /// + /// The type of the object returned by the functions. + /// + /// + /// The first function to evaluate. + /// + /// + /// The second function to evaluate. + /// + /// + /// The third function to evaluate. + /// + /// + /// A sequence with the values resulting from invoking , and . + /// + /// + /// , , or is . + /// /// - /// This operator uses deferred execution and streams the results. - /// If the resulting sequence is enumerated multiple times, the functions will be - /// invoked multiple times too. + /// This operator uses deferred execution and streams the results. If the resulting sequence is enumerated + /// multiple times, the functions will be invoked multiple times too. /// - /// The type of the object returned by the functions. - /// The first function to evaluate. - /// The second function to evaluate. - /// The third function to evaluate. - /// A sequence with the values resulting from invoking , and . - public static IEnumerable From(Func function1, Func function2, Func function3) { Guard.IsNotNull(function1); @@ -81,18 +111,25 @@ static IEnumerable Core(Func function1, Func function2, Func functio } /// - /// Returns a sequence containing the values resulting from invoking (in order) each function in the source sequence of functions. + /// Returns a sequence containing the values resulting from invoking (in order) each function in the source + /// sequence of functions. /// + /// + /// The type of the object returned by the functions. + /// + /// + /// The functions to evaluate. + /// + /// + /// A sequence with the values resulting from invoking all of the . + /// + /// + /// is . + /// /// - /// This operator uses deferred execution and streams the results. - /// If the resulting sequence is enumerated multiple times, the functions will be - /// invoked multiple times too. + /// This operator uses deferred execution and streams the results. If the resulting sequence is enumerated + /// multiple times, the functions will be invoked multiple times too. /// - /// The type of the object returned by the functions. - /// The functions to evaluate. - /// A sequence with the values resulting from invoking all of the . - /// When is . - public static IEnumerable From(params Func[] functions) => functions.Evaluate(); } From da01e42da3f3f20a4eb83b56c74e69ea070004d9 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 6 Sep 2023 10:46:14 -0500 Subject: [PATCH 040/124] Update documentation for `FullGroupJoin` --- ...SuperLinq.SuperEnumerable.FullGroupJoin.md | 27 +++ .../FullGroupJoin/FullGroupJoin1.linq | 46 ++++ .../FullGroupJoin/FullGroupJoin2.linq | 57 +++++ .../FullGroupJoin/FullGroupJoin3.linq | 48 ++++ .../FullGroupJoin/FullGroupJoin4.linq | 58 +++++ Source/SuperLinq/FullGroupJoin.cs | 228 ++++++++++++------ 6 files changed, 392 insertions(+), 72 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FullGroupJoin.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FullGroupJoin.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FullGroupJoin.md new file mode 100644 index 00000000..440712c4 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.FullGroupJoin.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.FullGroupJoin``3(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Func{``0,``2},System.Func{``1,``2}) +example: [*content] +--- +The following code example demonstrates how to execute a full group join using `FullGroupJoin` +[!code-csharp[](SuperLinq/FullGroupJoin/FullGroupJoin1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FullGroupJoin``3(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Func{``0,``2},System.Func{``1,``2},System.Collections.Generic.IEqualityComparer{``2}) +example: [*content] +--- +The following code example demonstrates how to execute a full group join using `FullGroupJoin` +[!code-csharp[](SuperLinq/FullGroupJoin/FullGroupJoin2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FullGroupJoin``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Func{``0,``2},System.Func{``1,``2},System.Func{``2,System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},``3}) +example: [*content] +--- +The following code example demonstrates how to execute a full group join using `FullGroupJoin` +[!code-csharp[](SuperLinq/FullGroupJoin/FullGroupJoin3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.FullGroupJoin``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Func{``0,``2},System.Func{``1,``2},System.Func{``2,System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},``3},System.Collections.Generic.IEqualityComparer{``2}) +example: [*content] +--- +The following code example demonstrates how to execute a full group join using `FullGroupJoin` +[!code-csharp[](SuperLinq/FullGroupJoin/FullGroupJoin4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin1.linq new file mode 100644 index 00000000..28374797 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin1.linq @@ -0,0 +1,46 @@ + + SuperLinq + SuperLinq + + +var people = new Person[] +{ + new("John Doe", 1), + new("Jane Doe", 1), + new("Lucy Ricardo", 2), + new("Ricky Ricardo", 2), + new("Fred Mertz", 3), + new("Ethel Mertz", 3), +}; + +var pets = new Pet[] +{ + new("Bear", 3), + new("Polly", 2), + new("Minnie", 2), + new("Mittens", 1), + new("Patches", 1), + new("Paws", 1), +}; + +var results = people + .FullGroupJoin( + pets, + p => p.FamilyId, + p => p.FamilyId); + +foreach (var (familyId, familyPeople, familyPets) in results) +{ + var str1 = string.Join(", ", familyPeople.Select(p => p.Name)); + var str2 = string.Join(", ", familyPets.Select(p => p.Name)); + Console.WriteLine($"({familyId}, [{str1}], [{str2}])"); +} + +// This code produces the following output: +// (1, [John Doe, Jane Doe], [Mittens, Patches, Paws]) +// (2, [Lucy Ricardo, Ricky Ricardo], [Polly, Minnie]) +// (3, [Fred Mertz, Ethel Mertz], [Bear]) + + +record Person(string Name, int FamilyId); +record Pet(string Name, int FamilyId); diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin2.linq new file mode 100644 index 00000000..a5dfe2c1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin2.linq @@ -0,0 +1,57 @@ + + SuperLinq + SuperLinq + System.Diagnostics.CodeAnalysis + + +var people = new Person[] +{ + new("John Doe", 1), + new("Jane Doe", 1), + new("Lucy Ricardo", 2), + new("Ricky Ricardo", 2), + new("Fred Mertz", 3), + new("Ethel Mertz", 3), +}; + +var pets = new Pet[] +{ + new("Bear", 103), + new("Polly", 102), + new("Minnie", 102), + new("Mittens", 101), + new("Patches", 101), + new("Paws", 101), +}; + +var results = people + .FullGroupJoin( + pets, + p => p.FamilyId, + p => p.FamilyId, + new IntBy100Comparer()); + +foreach (var (familyId, familyPeople, familyPets) in results) +{ + var str1 = string.Join(", ", familyPeople.Select(p => p.Name)); + var str2 = string.Join(", ", familyPets.Select(p => p.Name)); + Console.WriteLine($"({familyId}, [{str1}], [{str2}])"); +} + +// This code produces the following output: +// (1, [John Doe, Jane Doe], [Mittens, Patches, Paws]) +// (2, [Lucy Ricardo, Ricky Ricardo], [Polly, Minnie]) +// (3, [Fred Mertz, Ethel Mertz], [Bear]) + + +record Person(string Name, int FamilyId); +record Pet(string Name, int FamilyId); + +class IntBy100Comparer : IEqualityComparer +{ + public bool Equals(int x, int y) => + x % 100 == y % 100; + + public int GetHashCode(int obj) => + (obj % 100).GetHashCode(); +} diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin3.linq new file mode 100644 index 00000000..7f4444eb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin3.linq @@ -0,0 +1,48 @@ + + SuperLinq + SuperLinq + + +var people = new Person[] +{ + new("John Doe", 1), + new("Jane Doe", 1), + new("Lucy Ricardo", 2), + new("Ricky Ricardo", 2), + new("Fred Mertz", 3), + new("Ethel Mertz", 3), +}; + +var pets = new Pet[] +{ + new("Bear", 3), + new("Polly", 2), + new("Minnie", 2), + new("Mittens", 1), + new("Patches", 1), + new("Paws", 1), +}; + +var results = people + .FullGroupJoin( + pets, + p => p.FamilyId, + p => p.FamilyId, + (familyId, familyPeople, familyPets) => + { + var str1 = string.Join(", ", familyPeople.Select(p => p.Name)); + var str2 = string.Join(", ", familyPets.Select(p => p.Name)); + return $"({familyId}, [{str1}], [{str2}])"; + }); + +foreach (var str in results) + Console.WriteLine(str); + +// This code produces the following output: +// (1, [John Doe, Jane Doe], [Mittens, Patches, Paws]) +// (2, [Lucy Ricardo, Ricky Ricardo], [Polly, Minnie]) +// (3, [Fred Mertz, Ethel Mertz], [Bear]) + + +record Person(string Name, int FamilyId); +record Pet(string Name, int FamilyId); diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin4.linq new file mode 100644 index 00000000..65e30365 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FullGroupJoin/FullGroupJoin4.linq @@ -0,0 +1,58 @@ + + SuperLinq + SuperLinq + System.Diagnostics.CodeAnalysis + + +var people = new Person[] +{ + new("John Doe", 1), + new("Jane Doe", 1), + new("Lucy Ricardo", 2), + new("Ricky Ricardo", 2), + new("Fred Mertz", 3), + new("Ethel Mertz", 3), +}; + +var pets = new Pet[] +{ + new("Bear", 103), + new("Polly", 102), + new("Minnie", 102), + new("Mittens", 101), + new("Patches", 101), + new("Paws", 101), +}; + +var results = people + .FullGroupJoin( + pets, + p => p.FamilyId, + p => p.FamilyId, + (familyId, familyPeople, familyPets) => + { + var str1 = string.Join(", ", familyPeople.Select(p => p.Name)); + var str2 = string.Join(", ", familyPets.Select(p => p.Name)); + return $"({familyId}, [{str1}], [{str2}])"; + }, + new IntBy100Comparer()); + +foreach (var str in results) + Console.WriteLine(str); + +// This code produces the following output: +// (1, [John Doe, Jane Doe], [Mittens, Patches, Paws]) +// (2, [Lucy Ricardo, Ricky Ricardo], [Polly, Minnie]) +// (3, [Fred Mertz, Ethel Mertz], [Bear]) + +record Person(string Name, int FamilyId); +record Pet(string Name, int FamilyId); + +class IntBy100Comparer : IEqualityComparer +{ + public bool Equals(int x, int y) => + x % 100 == y % 100; + + public int GetHashCode(int obj) => + (obj % 100).GetHashCode(); +} diff --git a/Source/SuperLinq/FullGroupJoin.cs b/Source/SuperLinq/FullGroupJoin.cs index 9115e3b7..b2da94b6 100644 --- a/Source/SuperLinq/FullGroupJoin.cs +++ b/Source/SuperLinq/FullGroupJoin.cs @@ -4,25 +4,43 @@ public static partial class SuperEnumerable { /// - /// Performs a Full Group Join between the and sequences. + /// Performs a Full Group Join between the and sequences. /// + /// + /// The type of the elements in the first input sequence + /// + /// + /// The type of the elements in the second input sequence + /// + /// + /// The type of the key to use to join + /// + /// + /// First sequence + /// + /// + /// Second sequence + /// + /// + /// The mapping from first sequence to key + /// + /// + /// The mapping from second sequence to key + /// + /// + /// A sequence of elements joined from and . + /// + /// + /// , , , or is . + /// /// - /// This operator uses deferred execution and streams the results. - /// The results are yielded in the order of the elements found in the first sequence - /// followed by those found only in the second. In addition, the callback responsible - /// for projecting the results is supplied with sequences which preserve their source order. + /// This operator uses deferred execution and streams the results. The results are yielded in the order of the + /// elements found in the first sequence followed by those found only in the second. In addition, the callback + /// responsible for projecting the results is supplied with sequences which preserve their source order. /// - /// The type of the elements in the first input sequence - /// The type of the elements in the second input sequence - /// The type of the key to use to join - /// First sequence - /// Second sequence - /// The mapping from first sequence to key - /// The mapping from second sequence to key - /// A sequence of elements joined from and . - /// - - public static IEnumerable<(TKey Key, IEnumerable First, IEnumerable Second)> FullGroupJoin(this IEnumerable first, + public static IEnumerable<(TKey Key, IEnumerable First, IEnumerable Second)> FullGroupJoin( + this IEnumerable first, IEnumerable second, Func firstKeySelector, Func secondKeySelector) @@ -31,27 +49,47 @@ public static partial class SuperEnumerable } /// - /// Performs a Full Group Join between the and sequences. + /// Performs a Full Group Join between the and sequences. /// + /// + /// The type of the elements in the first input sequence + /// + /// + /// The type of the elements in the second input sequence + /// + /// + /// The type of the key to use to join + /// + /// + /// First sequence + /// + /// + /// Second sequence + /// + /// + /// The mapping from first sequence to key + /// + /// + /// The mapping from second sequence to key + /// + /// + /// The equality comparer to use to determine whether or not keys are equal. If , the + /// default equality comparer for is used. + /// + /// + /// A sequence of elements joined from and . + /// + /// + /// , , , or is . + /// /// - /// This operator uses deferred execution and streams the results. - /// The results are yielded in the order of the elements found in the first sequence - /// followed by those found only in the second. In addition, the callback responsible - /// for projecting the results is supplied with sequences which preserve their source order. + /// This operator uses deferred execution and streams the results. The results are yielded in the order of the + /// elements found in the first sequence followed by those found only in the second. In addition, the callback + /// responsible for projecting the results is supplied with sequences which preserve their source order. /// - /// The type of the elements in the first input sequence - /// The type of the elements in the second input sequence - /// The type of the key to use to join - /// First sequence - /// Second sequence - /// The mapping from first sequence to key - /// The mapping from second sequence to key - /// The equality comparer to use to determine whether or not keys are equal. - /// If null, the default equality comparer for is used. - /// A sequence of elements joined from and . - /// - - public static IEnumerable<(TKey Key, IEnumerable First, IEnumerable Second)> FullGroupJoin(this IEnumerable first, + public static IEnumerable<(TKey Key, IEnumerable First, IEnumerable Second)> FullGroupJoin( + this IEnumerable first, IEnumerable second, Func firstKeySelector, Func secondKeySelector, @@ -61,27 +99,49 @@ public static partial class SuperEnumerable } /// - /// Performs a full group-join between two sequences. + /// Performs a full group-join between two sequences. /// + /// + /// The type of the elements in the first input sequence + /// + /// + /// The type of the elements in the second input sequence + /// + /// + /// The type of the key to use to join + /// + /// + /// The type of the elements of the resulting sequence + /// + /// + /// First sequence + /// + /// + /// Second sequence + /// + /// + /// The mapping from first sequence to key + /// + /// + /// The mapping from second sequence to key + /// + /// + /// Function to apply to each pair of elements plus the key + /// + /// + /// A sequence of elements joined from and . + /// + /// + /// , , , , or is . + /// /// - /// This operator uses deferred execution and streams the results. - /// The results are yielded in the order of the elements found in the first sequence - /// followed by those found only in the second. In addition, the callback responsible - /// for projecting the results is supplied with sequences which preserve their source order. + /// This operator uses deferred execution and streams the results. The results are yielded in the order of the + /// elements found in the first sequence followed by those found only in the second. In addition, the callback + /// responsible for projecting the results is supplied with sequences which preserve their source order. /// - /// The type of the elements in the first input sequence - /// The type of the elements in the second input sequence - /// The type of the key to use to join - /// The type of the elements of the resulting sequence - /// First sequence - /// Second sequence - /// The mapping from first sequence to key - /// The mapping from second sequence to key - /// Function to apply to each pair of elements plus the key - /// A sequence of elements joined from and . - /// - - public static IEnumerable FullGroupJoin(this IEnumerable first, + public static IEnumerable FullGroupJoin( + this IEnumerable first, IEnumerable second, Func firstKeySelector, Func secondKeySelector, @@ -91,29 +151,53 @@ public static IEnumerable FullGroupJoin } /// - /// Performs a full group-join between two sequences. + /// Performs a full group-join between two sequences. /// + /// + /// The type of the elements in the first input sequence + /// + /// + /// The type of the elements in the second input sequence + /// + /// + /// The type of the key to use to join + /// + /// + /// The type of the elements of the resulting sequence + /// + /// + /// First sequence + /// + /// + /// Second sequence + /// + /// + /// The mapping from first sequence to key + /// + /// + /// The mapping from second sequence to key + /// + /// + /// Function to apply to each pair of elements plus the key + /// + /// + /// The equality comparer to use to determine whether or not keys are equal. If , the + /// default equality comparer for is used. + /// + /// + /// A sequence of elements joined from and . + /// + /// + /// , , , , or is . + /// /// - /// This operator uses deferred execution and streams the results. - /// The results are yielded in the order of the elements found in the first sequence - /// followed by those found only in the second. In addition, the callback responsible - /// for projecting the results is supplied with sequences which preserve their source order. + /// This operator uses deferred execution and streams the results. The results are yielded in the order of the + /// elements found in the first sequence followed by those found only in the second. In addition, the callback + /// responsible for projecting the results is supplied with sequences which preserve their source order. /// - /// The type of the elements in the first input sequence - /// The type of the elements in the second input sequence - /// The type of the key to use to join - /// The type of the elements of the resulting sequence - /// First sequence - /// Second sequence - /// The mapping from first sequence to key - /// The mapping from second sequence to key - /// Function to apply to each pair of elements plus the key - /// The equality comparer to use to determine whether or not keys are equal. - /// If null, the default equality comparer for is used. - /// A sequence of elements joined from and . - /// - - public static IEnumerable FullGroupJoin(this IEnumerable first, + public static IEnumerable FullGroupJoin( + this IEnumerable first, IEnumerable second, Func firstKeySelector, Func secondKeySelector, From 32ca46963a234691e607307b0b8cd5f05a17146d Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 6 Sep 2023 17:47:59 -0500 Subject: [PATCH 041/124] Update documentation for `Generate` --- .../SuperLinq.SuperEnumerable.Generate.md | 6 ++++ .../apidoc/SuperLinq/Generate/Generate.linq | 17 +++++++++++ Source/SuperLinq/Generate.cs | 30 ++++++++++--------- 3 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Generate.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Generate/Generate.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Generate.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Generate.md new file mode 100644 index 00000000..298b08f2 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Generate.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Generate``1(``0,System.Func{``0,``0}) +example: [*content] +--- +The following code example demonstrates how to generate a sequence from a generator function using `Generate`. +[!code-csharp[](SuperLinq/Generate/Generate.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Generate/Generate.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Generate/Generate.linq new file mode 100644 index 00000000..4dc73169 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Generate/Generate.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +// Generate a sequence using a generator function +var result = SuperEnumerable + .Generate(1, n => n * 2) + .Take(10); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 4, 8, 16, 32, 64, 128, 256, 512] diff --git a/Source/SuperLinq/Generate.cs b/Source/SuperLinq/Generate.cs index 82aa9c5d..67edf821 100644 --- a/Source/SuperLinq/Generate.cs +++ b/Source/SuperLinq/Generate.cs @@ -3,25 +3,27 @@ public static partial class SuperEnumerable { /// - /// Returns a sequence of values consecutively generated by a generator function. + /// Returns a sequence of values consecutively generated by a generator function. /// - /// Type of elements to generate. - /// Value of first element in sequence + /// + /// Type of elements to generate. + /// + /// + /// Value of first element in sequence + /// /// - /// Generator function which takes the previous series element and uses it to generate the next element. + /// Generator function which takes the previous series element and uses it to generate the next element. /// - /// A sequence containing the generated values. - /// is . + /// + /// A sequence containing the generated values. + /// + /// + /// is . + /// /// - /// This function defers element generation until needed and streams the results. + /// This function defers element generation until needed and streams the results. It is treated as an + /// infinite sequence, and will not terminate. /// - /// - /// n * n).Take(5); - /// ]]> - /// The result variable, when iterated over, will yield 2, 4, 16, 256, and 65536, in turn. - /// - public static IEnumerable Generate(TResult initial, Func generator) { Guard.IsNotNull(generator); From f7a9fef2db4adf3bf0c948c7f2ac4831e5a5e823 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 12 Oct 2023 16:19:30 -0500 Subject: [PATCH 042/124] Update documentation for `GetShortestPath` --- ...perLinq.SuperEnumerable.GetShortestPath.md | 55 ++++ .../GetShortestPath1.linq | 34 ++ .../GetShortestPath2.linq | 48 +++ .../GetShortestPath3.linq | 34 ++ .../GetShortestPath4.linq | 48 +++ .../GetShortestPath1.linq | 40 +++ .../GetShortestPath2.linq | 42 +++ .../GetShortestPath3.linq | 40 +++ .../GetShortestPath4.linq | 51 +++ Source/SuperLinq/GetShortestPath.A-Star.cs | 300 ++++++++++-------- Source/SuperLinq/GetShortestPath.Dijkstra.cs | 273 +++++++++------- Tests/SuperLinq.Test/GetShortestPathTest.cs | 43 +++ 12 files changed, 754 insertions(+), 254 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPath.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPath.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPath.md new file mode 100644 index 00000000..90deb9ff --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPath.md @@ -0,0 +1,55 @@ +--- +uid: SuperLinq.SuperEnumerable.GetShortestPath``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1}}},``0) +example: [*content] +--- +The following code example demonstrates how to use Dijkstra's algorithm to find the shortest path using `GetShortestPath`. +[!code-csharp[](SuperLinq/GetShortestPath.Dijkstra/GetShortestPath1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPath``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1}}},``0,System.Collections.Generic.IEqualityComparer{``0},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to use Dijkstra's algorithm to find the shortest path using `GetShortestPath`. +[!code-csharp[](SuperLinq/GetShortestPath.Dijkstra/GetShortestPath2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPath``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1}}},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to use Dijkstra's algorithm to find the shortest path using `GetShortestPath`. +[!code-csharp[](SuperLinq/GetShortestPath.Dijkstra/GetShortestPath3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPath``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1}}},System.Func{``0,System.Boolean},System.Collections.Generic.IEqualityComparer{``0},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to use Dijkstra's algorithm to find the shortest path using `GetShortestPath`. +[!code-csharp[](SuperLinq/GetShortestPath.Dijkstra/GetShortestPath4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPath``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1,``1}}},``0) +example: [*content] +--- +The following code example demonstrates how to use A* to find the shortest path using `GetShortestPath`. +[!code-csharp[](SuperLinq/GetShortestPath.AStar/GetShortestPath1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPath``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1,``1}}},``0,System.Collections.Generic.IEqualityComparer{``0},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to use A* to find the shortest path using `GetShortestPath`. +[!code-csharp[](SuperLinq/GetShortestPath.AStar/GetShortestPath2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPath``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1,``1}}},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to use A* to find the shortest path using `GetShortestPath`. +[!code-csharp[](SuperLinq/GetShortestPath.AStar/GetShortestPath3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPath``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1,``1}}},System.Func{``0,System.Boolean},System.Collections.Generic.IEqualityComparer{``0},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to use A* to find the shortest path using `GetShortestPath`. +[!code-csharp[](SuperLinq/GetShortestPath.AStar/GetShortestPath4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath1.linq new file mode 100644 index 00000000..d774f43f --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath1.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var start = (x: 0, y: 0); +var end = (x: 2, y: 2); +((int x, int y) p, double cost, double bestGuess) GetNeighbor((int x, int y) p, double newCost) +{ + var xD = p.x - end.x; + var yD = p.y - end.y; + var dist = Math.Sqrt((xD * xD) + (yD * yD)); + return (p, newCost, newCost + dist); +} + +IEnumerable<((int x, int y) p, double cost, double bestGuess)> GetNeighbors((int x, int y) p, double cost) +{ + yield return GetNeighbor((p.x + 1, p.y), cost + 1.001d); + yield return GetNeighbor((p.x, p.y + 1), cost + 1.002d); + yield return GetNeighbor((p.x - 1, p.y), cost + 1.003d); + yield return GetNeighbor((p.x, p.y - 1), cost + 1.004d); +} + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPath<(int x, int y), double>( + start, + GetNeighbors, + end); + +Console.WriteLine(string.Join(" -> ", result.Select(x => $"({x.nextState}, {x.cost:N3})"))); + +// This code produces the following output: +// ((0, 0), 0.000) -> ((1, 0), 1.001) -> ((2, 0), 2.002) -> ((2, 1), 3.004) -> ((2, 2), 4.006) diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath2.linq new file mode 100644 index 00000000..0c4bec61 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath2.linq @@ -0,0 +1,48 @@ + + SuperLinq + SuperLinq + + +var start = (x: 0, y: 0); +var end = (x: -2, y: -2); +((int x, int y) p, double cost, double bestGuess) GetNeighbor((int x, int y) p, double newCost) +{ + var xD = p.x - end.x; + var yD = p.y - end.y; + var dist = Math.Sqrt((xD * xD) + (yD * yD)); + return (p, newCost, newCost + dist); +} + +IEnumerable<((int x, int y) p, double cost, double bestGuess)> GetNeighbors((int x, int y) p, double cost) +{ + yield return GetNeighbor((p.x + 1, p.y), cost + 1.001d); + yield return GetNeighbor((p.x, p.y + 1), cost + 1.002d); + yield return GetNeighbor((p.x - 1, p.y), cost + 1.003d); + yield return GetNeighbor((p.x, p.y - 1), cost + 1.004d); +} + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPath<(int x, int y), double>( + start, + GetNeighbors, + end, + new PointComparer(), + null); + +Console.WriteLine(string.Join(" -> ", result.Select(x => $"({x.nextState}, {x.cost:N3})"))); + +// This code produces the following output: +// ((0, 0), 0.000) -> ((-1, 0), 1.003) -> ((-1, -1), 2.007) -> ((-2, -1), 3.010) -> ((-2, -2), 4.014) + +class PointComparer : IEqualityComparer<(int x, int y)> +{ + public bool Equals((int x, int y) x, (int x, int y) y) => + ManhattanDistance(x) == ManhattanDistance(y); + + public int GetHashCode((int x, int y) obj) => + ManhattanDistance(obj).GetHashCode(); + + private static double ManhattanDistance((int x, int y) obj) => + Math.Sqrt((obj.x * obj.x) + (obj.y * obj.y)); +} \ No newline at end of file diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath3.linq new file mode 100644 index 00000000..c433c00d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath3.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var start = (x: 0, y: 0); +var end = (x: 2, y: 2); +((int x, int y) p, double cost, double bestGuess) GetNeighbor((int x, int y) p, double newCost) +{ + var xD = p.x - end.x; + var yD = p.y - end.y; + var dist = Math.Sqrt((xD * xD) + (yD * yD)); + return (p, newCost, newCost + dist); +} + +IEnumerable<((int x, int y) p, double cost, double bestGuess)> GetNeighbors((int x, int y) p, double cost) +{ + yield return GetNeighbor((p.x + 1, p.y), cost + 1.001d); + yield return GetNeighbor((p.x, p.y + 1), cost + 1.002d); + yield return GetNeighbor((p.x - 1, p.y), cost + 1.003d); + yield return GetNeighbor((p.x, p.y - 1), cost + 1.004d); +} + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPath<(int x, int y), double>( + start, + GetNeighbors, + state => state == end); + +Console.WriteLine(string.Join(" -> ", result.Select(x => $"({x.nextState}, {x.cost:N3})"))); + +// This code produces the following output: +// ((0, 0), 0.000) -> ((1, 0), 1.001) -> ((2, 0), 2.002) -> ((2, 1), 3.004) -> ((2, 2), 4.006) diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath4.linq new file mode 100644 index 00000000..f5615015 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.AStar/GetShortestPath4.linq @@ -0,0 +1,48 @@ + + SuperLinq + SuperLinq + + +var start = (x: 0, y: 0); +var end = (x: -2, y: -2); +((int x, int y) p, double cost, double bestGuess) GetNeighbor((int x, int y) p, double newCost) +{ + var xD = p.x - end.x; + var yD = p.y - end.y; + var dist = Math.Sqrt((xD * xD) + (yD * yD)); + return (p, newCost, newCost + dist); +} + +IEnumerable<((int x, int y) p, double cost, double bestGuess)> GetNeighbors((int x, int y) p, double cost) +{ + yield return GetNeighbor((p.x + 1, p.y), cost + 1.001d); + yield return GetNeighbor((p.x, p.y + 1), cost + 1.002d); + yield return GetNeighbor((p.x - 1, p.y), cost + 1.003d); + yield return GetNeighbor((p.x, p.y - 1), cost + 1.004d); +} + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPath<(int x, int y), double>( + start, + GetNeighbors, + state => new PointComparer().Equals(state, end), + new PointComparer(), + null); + +Console.WriteLine(string.Join(" -> ", result.Select(x => $"({x.nextState}, {x.cost:N3})"))); + +// This code produces the following output: +// ((0, 0), 0.000) -> ((-1, 0), 1.003) -> ((-1, -1), 2.007) -> ((-2, -1), 3.010) -> ((-2, -2), 4.014) + +class PointComparer : IEqualityComparer<(int x, int y)> +{ + public bool Equals((int x, int y) x, (int x, int y) y) => + ManhattanDistance(x) == ManhattanDistance(y); + + public int GetHashCode((int x, int y) obj) => + ManhattanDistance(obj).GetHashCode(); + + private static double ManhattanDistance((int x, int y) obj) => + Math.Sqrt((obj.x * obj.x) + (obj.y * obj.y)); +} \ No newline at end of file diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath1.linq new file mode 100644 index 00000000..89bee003 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath1.linq @@ -0,0 +1,40 @@ + + SuperLinq + SuperLinq + + +var costs = + new[] + { + (from: "start", to: "a", cost: 1), + (from: "a", to: "b", cost: 2), + (from: "b", to: "c", cost: 3), + (from: "c", to: "d", cost: 4), + (from: "d", to: "end", cost: 5), + (from: "start", to: "A", cost: 10), + (from: "A", to: "B", cost: 20), + (from: "B", to: "C", cost: 30), + (from: "C", to: "D", cost: 40), + (from: "D", to: "end", cost: 50), + (from: "start", to: "END", cost: 10), + (from: "start", to: "END", cost: 1000), + }; +var map = costs + .Concat(costs.Select(x => (from: x.to, to: x.from, x.cost))) + .Where(x => + x.to != "start" + && x.from != "end") + .ToLookup(x => x.from, x => (x.to, x.cost)); + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPath( + "start", + (state, cost) => map[state] + .Select(x => (x.to, x.cost + cost)), + "end"); + +Console.WriteLine(string.Join(" -> ", result)); + +// This code produces the following output: +// (start, 0) -> (a, 1) -> (b, 3) -> (c, 6) -> (d, 10) -> (end, 15) diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath2.linq new file mode 100644 index 00000000..d7b340cc --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath2.linq @@ -0,0 +1,42 @@ + + SuperLinq + SuperLinq + + +var costs = + new[] + { + (from: "start", to: "a", cost: 1), + (from: "a", to: "b", cost: 2), + (from: "b", to: "c", cost: 3), + (from: "c", to: "d", cost: 4), + (from: "d", to: "end", cost: 5), + (from: "start", to: "A", cost: 10), + (from: "A", to: "B", cost: 20), + (from: "B", to: "C", cost: 30), + (from: "C", to: "D", cost: 40), + (from: "D", to: "end", cost: 50), + (from: "start", to: "END", cost: 10), + (from: "start", to: "END", cost: 1000), + }; +var map = costs + .Concat(costs.Select(x => (from: x.to, to: x.from, x.cost))) + .Where(x => + x.to != "start" + && x.from != "end") + .ToLookup(x => x.from, x => (x.to, x.cost), StringComparer.OrdinalIgnoreCase); + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPath( + "start", + (state, cost) => map[state] + .Select(x => (x.to, x.cost + cost)), + "end", + StringComparer.OrdinalIgnoreCase, + default); + +Console.WriteLine(string.Join(" -> ", result)); + +// This code produces the following output: +// (start, 0) -> (END, 10) diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath3.linq new file mode 100644 index 00000000..48380ad9 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath3.linq @@ -0,0 +1,40 @@ + + SuperLinq + SuperLinq + + +var costs = + new[] + { + (from: (id: "start", index: 1), to: (id: "a", index: 2), cost: 1), + (from: (id: "a", index: 2), to: (id: "b", index: 3), cost: 2), + (from: (id: "b", index: 3), to: (id: "c", index: 3), cost: 3), + (from: (id: "c", index: 3), to: (id: "d", index: 4), cost: 4), + (from: (id: "d", index: 4), to: (id: "end", index: 5), cost: 5), + (from: (id: "start", index: 1), to: (id: "A", index: 6), cost: 10), + (from: (id: "A", index: 6), to: (id: "B", index: 7), cost: 20), + (from: (id: "B", index: 7), to: (id: "C", index: 8), cost: 30), + (from: (id: "C", index: 8), to: (id: "D", index: 9), cost: 40), + (from: (id: "D", index: 9), to: (id: "end", index: 5), cost: 50), + (from: (id: "start", index: 1), to: (id: "END", index: 10), cost: 10), + (from: (id: "start", index: 1), to: (id: "END", index: 10), cost: 1000), + }; +var map = costs + .Concat(costs.Select(x => (from: x.to, to: x.from, x.cost))) + .Where(x => + x.to.id != "start" + && x.from.id != "end") + .ToLookup(x => x.from.id, x => (x.to, x.cost)); + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPath<(string id, int index), int>( + ("start", 1), + (state, cost) => map[state.id] + .Select(x => (x.to, x.cost + cost)), + x => x.id.Equals("end", StringComparison.OrdinalIgnoreCase)); + +Console.WriteLine(string.Join(" -> ", result)); + +// This code produces the following output: +// ((start, 1), 0) -> ((a, 2), 1) -> ((b, 3), 3) -> ((c, 3), 6) -> ((d, 4), 10) -> ((end, 5), 15) diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath4.linq new file mode 100644 index 00000000..304a56cf --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPath.Dijkstra/GetShortestPath4.linq @@ -0,0 +1,51 @@ + + SuperLinq + SuperLinq + + +var costs = + new[] + { + (from: (id: "start", index: 1), to: (id: "a", index: 2), cost: 1), + (from: (id: "a", index: 2), to: (id: "b", index: 3), cost: 2), + (from: (id: "b", index: 3), to: (id: "c", index: 3), cost: 3), + (from: (id: "c", index: 3), to: (id: "d", index: 4), cost: 4), + (from: (id: "d", index: 4), to: (id: "end", index: 5), cost: 5), + (from: (id: "start", index: 1), to: (id: "A", index: 6), cost: 10), + (from: (id: "A", index: 6), to: (id: "B", index: 7), cost: 20), + (from: (id: "B", index: 7), to: (id: "C", index: 8), cost: 30), + (from: (id: "C", index: 8), to: (id: "D", index: 9), cost: 40), + (from: (id: "D", index: 9), to: (id: "end", index: 5), cost: 50), + (from: (id: "start", index: 1), to: (id: "END", index: 10), cost: 10), + (from: (id: "start", index: 1), to: (id: "END", index: 10), cost: 1000), + }; +var map = costs + .Concat(costs.Select(x => (from: x.to, to: x.from, x.cost))) + .Where(x => + x.to.id != "start" + && x.from.id != "end") + .ToLookup(x => x.from.id, x => (x.to, x.cost), StringComparer.OrdinalIgnoreCase); + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPath<(string id, int index), int>( + ("start", 1), + (state, cost) => map[state.id] + .Select(x => (x.to, x.cost + cost)), + x => x.id.Equals("end", StringComparison.OrdinalIgnoreCase), + new StateComparer(), + default); + +Console.WriteLine(string.Join(" -> ", result)); + +// This code produces the following output: +// ((start, 1), 0) -> ((END, 10), 10) + +class StateComparer : IEqualityComparer<(string id, int index)> +{ + public bool Equals((string id, int index) x, (string id, int index) y) => + StringComparer.OrdinalIgnoreCase.Equals(x.id, y.id); + + public int GetHashCode((string id, int index) obj) => + StringComparer.OrdinalIgnoreCase.GetHashCode(obj.id); +} diff --git a/Source/SuperLinq/GetShortestPath.A-Star.cs b/Source/SuperLinq/GetShortestPath.A-Star.cs index 81b0c775..02c19026 100644 --- a/Source/SuperLinq/GetShortestPath.A-Star.cs +++ b/Source/SuperLinq/GetShortestPath.A-Star.cs @@ -5,62 +5,62 @@ namespace SuperLinq; public partial class SuperEnumerable { /// - /// Find the shortest path from - /// state to state , - /// using the A* algorithm. + /// Find the shortest path from state to state , using the A* + /// algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state; - /// the total cost to get to that state based on the - /// traversal cost at the current state; and the predicted - /// or best-guess total (already traversed plus remaining) - /// cost to get to . + /// A function that returns the neighbors for a given state; the total cost to get to that state based on the + /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus + /// remaining) cost to get to . + /// + /// + /// The target state /// - /// The target state /// - /// The traversal path and cost of the shortest path from - /// to . + /// The traversal path and cost of the shortest path from to . /// - /// is . - /// The map is entirely explored and no path to is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no path to is found. + /// /// /// - /// This method uses the A* algorithm to explore a map - /// and find the shortest path from - /// to . An - /// is used to manage the list of s - /// to process, to reduce the computation cost of this operator. - /// Overall performance of this method will depend on the reliability - /// of the best-guess cost provided by . + /// This method uses the A* algorithm to explore a map and find the shortest path from + /// to . An is used to manage + /// the list of s to process, to reduce the computation cost of this operator. + /// Overall performance of this method will depend on the reliability of the best-guess cost provided by + /// . /// /// - /// Loops and cycles are automatically detected and handled - /// correctly by this operator; only the cheapest path to - /// a given is used, and other - /// paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// The A* algorithm assumes that all costs are positive, - /// that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption - /// will have undefined behavior. + /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, - /// performance will depend on how many states are required to - /// be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This method uses - /// to compare s and - /// to compare traversal + /// This method uses to compare s and + /// to compare traversal /// s. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static IEnumerable<(TState nextState, TCost? cost)> @@ -80,58 +80,63 @@ public partial class SuperEnumerable } /// - /// Find the shortest path from - /// state to state , - /// using the A* algorithm. + /// Find the shortest path from state to state , using the A* + /// algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state; - /// the total cost to get to that state based on the - /// traversal cost at the current state; and the predicted - /// or best-guess total (already traversed plus remaining) - /// cost to get to . + /// A function that returns the neighbors for a given state; the total cost to get to that state based on the + /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus + /// remaining) cost to get to . + /// + /// + /// The target state + /// + /// + /// A custom equality comparer for + /// + /// + /// A custom comparer for /// - /// The target state - /// A custom equality comparer for - /// A custom comparer for /// - /// The traversal path and cost of the shortest path from - /// to . + /// The traversal path and cost of the shortest path from to . /// - /// is . - /// The map is entirely explored and no path to is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no path to is found. + /// /// /// - /// This method uses the A* algorithm to explore a map - /// and find the shortest path from - /// to . An - /// is used to manage the list of s - /// to process, to reduce the computation cost of this operator. - /// Overall performance of this method will depend on the reliability - /// of the best-guess cost provided by . + /// This method uses the A* algorithm to explore a map and find the shortest path from + /// to . An is used to manage + /// the list of s to process, to reduce the computation cost of this operator. + /// Overall performance of this method will depend on the reliability of the best-guess cost provided by + /// . /// /// - /// Loops and cycles are automatically detected and handled - /// correctly by this operator; only the cheapest path to - /// a given is used, and other - /// paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// The A* algorithm assumes that all costs are positive, - /// that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption - /// will have undefined behavior. + /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, - /// performance will depend on how many states are required to - /// be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static IEnumerable<(TState nextState, TCost? cost)> @@ -156,52 +161,64 @@ public partial class SuperEnumerable } /// - /// Find the shortest path from state to a state that satisfies the conditions expressed by - /// , using the A* algorithm. + /// Find the shortest path from state to a state that satisfies the conditions + /// expressed by , using the A* algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state; the total cost to get to that state based on the - /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus remaining) - /// cost to get to a state that satisfies the conditions expressed by . + /// A function that returns the neighbors for a given state; the total cost to get to that state based on the + /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus + /// remaining) cost to get to a state that satisfies the conditions expressed by . + /// + /// + /// The predicate that defines the conditions of the element to search for. /// - /// The predicate that defines the conditions of the element to search for. /// - /// The traversal path and cost of the shortest path from to a state that satisfies the - /// conditions expressed by . + /// The traversal path and cost of the shortest path from to a state that satisfies the + /// conditions expressed by . /// - /// is . - /// The map is entirely explored and no state that satisfies the - /// conditions expressed by is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no state that satisfies the conditions expressed by is found. + /// /// /// - /// This method uses the A* algorithm to explore a map and find the shortest path from to - /// a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. Overall performance of this - /// method will depend on the reliability of the best-guess cost provided by . + /// This method uses the A* algorithm to explore a map and find the shortest path from + /// to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. Overall performance of this + /// method will depend on the reliability of the best-guess cost provided by . /// /// - /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path to a - /// given is used, and other paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption will have undefined behavior. + /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, performance will depend on how many states are required - /// to be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This method uses to compare s and to compare traversal + /// This method uses to compare s and + /// to compare traversal /// s. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static IEnumerable<(TState nextState, TCost? cost)> @@ -221,54 +238,65 @@ public partial class SuperEnumerable } /// - /// Find the shortest path from state to a state that satisfies the conditions expressed by - /// , using the A* algorithm. + /// Find the shortest path from state to a state that satisfies the conditions + /// expressed by , using the A* algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state; the total cost to get to that state based on the - /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus remaining) - /// cost to get to a state that satisfies the conditions expressed by . + /// A function that returns the neighbors for a given state; the total cost to get to that state based on the + /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus + /// remaining) cost to get to a state that satisfies the conditions expressed by . + /// + /// + /// The predicate that defines the conditions of the element to search for. + /// + /// + /// A custom equality comparer for + /// + /// + /// A custom comparer for /// - /// The predicate that defines the conditions of the element to search for. - /// A custom equality comparer for - /// A custom comparer for /// - /// The traversal path and cost of the shortest path from to a state that satisfies the - /// conditions expressed by . + /// The traversal path and cost of the shortest path from to a state that satisfies the + /// conditions expressed by . /// - /// is . - /// The map is entirely explored and no state that satisfies the - /// conditions expressed by is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no state that satisfies the conditions expressed by is found. + /// /// /// - /// This method uses the A* algorithm to explore a map and find the shortest path from to - /// a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. Overall performance of this - /// method will depend on the reliability of the best-guess cost provided by . + /// This method uses the A* algorithm to explore a map and find the shortest path from + /// to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. Overall performance of this + /// method will depend on the reliability of the best-guess cost provided by . /// /// - /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path to a - /// given is used, and other paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption will have undefined behavior. + /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, performance will depend on how many states are required - /// to be evaluated before reaching the target point. - /// - /// - /// This method uses to compare s and to compare traversal - /// s. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static IEnumerable<(TState nextState, TCost? cost)> diff --git a/Source/SuperLinq/GetShortestPath.Dijkstra.cs b/Source/SuperLinq/GetShortestPath.Dijkstra.cs index 3e0e3c8b..51390e86 100644 --- a/Source/SuperLinq/GetShortestPath.Dijkstra.cs +++ b/Source/SuperLinq/GetShortestPath.Dijkstra.cs @@ -5,58 +5,60 @@ namespace SuperLinq; public partial class SuperEnumerable { /// - /// Find the shortest path from - /// state to state , - /// using Dijkstra's algorithm. + /// Find the shortest path from state to state , using Dijkstra's + /// algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state - /// and the total cost to get to that state based on the - /// traversal cost at the current state. + /// A function that returns the neighbors for a given state and the total cost to get to that state based on the + /// traversal cost at the current state. + /// + /// + /// The target state /// - /// The target state /// - /// The traversal path and cost of the shortest path from - /// to . + /// The traversal path and cost of the shortest path from to . /// - /// is . - /// The map is entirely explored and no path to is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no path to is found. + /// /// /// - /// This method uses Dijkstra's algorithm to explore a map - /// and find the shortest path from - /// to . An - /// is used to manage the list of s - /// to process, to reduce the computation cost of this operator. + /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from to . An is + /// used to manage the list of s to process, to reduce the computation cost of this + /// operator. /// /// - /// Loops and cycles are automatically detected and handled - /// correctly by this operator; only the cheapest path to - /// a given is used, and other - /// paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// Dijkstra's algorithm assumes that all costs are positive, - /// that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption - /// will have undefined behavior. + /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, - /// performance will depend on how many states are required to - /// be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This method uses - /// to compare s and - /// to compare traversal + /// This method uses to compare s and + /// to compare traversal /// s. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static IEnumerable<(TState nextState, TCost? cost)> @@ -76,54 +78,61 @@ public partial class SuperEnumerable } /// - /// Find the shortest path from - /// state to state , - /// using Dijkstra's algorithm. + /// Find the shortest path from state to state , using Dijkstra's + /// algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state - /// and the total cost to get to that state based on the - /// traversal cost at the current state. + /// A function that returns the neighbors for a given state and the total cost to get to that state based on the + /// traversal cost at the current state. + /// + /// + /// The target state + /// + /// + /// A custom equality comparer for + /// + /// + /// A custom comparer for /// - /// The target state - /// A custom equality comparer for - /// A custom comparer for /// - /// The traversal path and cost of the shortest path from - /// to . + /// The traversal path and cost of the shortest path from to . /// - /// is . - /// The map is entirely explored and no path to is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no path to is found. + /// /// /// - /// This method uses Dijkstra's algorithm to explore a map - /// and find the shortest path from - /// to . An - /// is used to manage the list of s - /// to process, to reduce the computation cost of this operator. + /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from to . An is + /// used to manage the list of s to process, to reduce the computation cost of this + /// operator. /// /// - /// Loops and cycles are automatically detected and handled - /// correctly by this operator; only the cheapest path to - /// a given is used, and other - /// paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// Dijkstra's algorithm assumes that all costs are positive, - /// that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption - /// will have undefined behavior. + /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, - /// performance will depend on how many states are required to - /// be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static IEnumerable<(TState state, TCost? cost)> @@ -148,50 +157,62 @@ public partial class SuperEnumerable } /// - /// Find the shortest path from state to a state that satisfies the conditions expressed by - /// , using Dijkstra's algorithm. + /// Find the shortest path from state to a state that satisfies the conditions + /// expressed by , using Dijkstra's algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state and the total cost to get to that state based on the - /// traversal cost at the current state. + /// A function that returns the neighbors for a given state and the total cost to get to that state based on the + /// traversal cost at the current state. /// - /// The predicate that defines the conditions of the element to search for. - /// + /// + /// The predicate that defines the conditions of the element to search for. + /// + /// /// The traversal path and cost of the shortest path from to a state that satisfies the /// conditions expressed by . /// - /// is . - /// The map is entirely explored and no state that satisfies the - /// conditions expressed by is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no state that satisfies the conditions expressed by is found. + /// /// /// - /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from - /// to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. + /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. /// /// - /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path to a - /// given is used, and other paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a - /// negative distance from one state to the next. Violating this assumption will have undefined behavior. + /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, performance will depend on how many states are required - /// to be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This method uses to compare s and to compare traversal + /// This method uses to compare s and + /// to compare traversal /// s. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static IEnumerable<(TState nextState, TCost? cost)> @@ -211,47 +232,63 @@ public partial class SuperEnumerable } /// - /// Find the shortest path from state to a state that satisfies the conditions expressed by - /// , using Dijkstra's algorithm. + /// Find the shortest path from state to a state that satisfies the conditions + /// expressed by , using Dijkstra's algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state and the total cost to get to that state based on the - /// traversal cost at the current state. + /// A function that returns the neighbors for a given state and the total cost to get to that state based on the + /// traversal cost at the current state. + /// + /// + /// The predicate that defines the conditions of the element to search for. + /// + /// + /// A custom equality comparer for + /// + /// + /// A custom comparer for /// - /// The predicate that defines the conditions of the element to search for. - /// A custom equality comparer for - /// A custom comparer for /// - /// The traversal path and cost of the shortest path from to a state that satisfies the - /// conditions expressed by . + /// The traversal path and cost of the shortest path from to a state that satisfies the + /// conditions expressed by . /// - /// is . - /// The map is entirely explored and no state that satisfies the - /// conditions expressed by is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no state that satisfies the conditions expressed by is found. + /// /// /// - /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from - /// to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. + /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. /// /// - /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path to a - /// given is used, and other paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a - /// negative distance from one state to the next. Violating this assumption will have undefined behavior. + /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, performance will depend on how many states are required - /// to be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static IEnumerable<(TState state, TCost? cost)> diff --git a/Tests/SuperLinq.Test/GetShortestPathTest.cs b/Tests/SuperLinq.Test/GetShortestPathTest.cs index d25b1306..92a4573a 100644 --- a/Tests/SuperLinq.Test/GetShortestPathTest.cs +++ b/Tests/SuperLinq.Test/GetShortestPathTest.cs @@ -539,6 +539,49 @@ public void GetRegularMapPath() sequences.VerifySequences(); } + [Fact] + public void Test() + { + var start = (x: 0, y: 0); + var end = (x: -2, y: -2); + ((int x, int y) p, double cost, double bestGuess) GetNeighbor((int x, int y) p, double newCost) + { + var xD = p.x - end.x; + var yD = p.y - end.y; + var dist = Math.Sqrt((xD * xD) + (yD * yD)); + return (p, newCost, newCost + dist); + } + + IEnumerable<((int x, int y) p, double cost, double bestGuess)> GetNeighbors((int x, int y) p, double cost) + { + yield return GetNeighbor((p.x + 1, p.y), cost + 1.001d); + yield return GetNeighbor((p.x, p.y + 1), cost + 1.002d); + yield return GetNeighbor((p.x - 1, p.y), cost + 1.003d); + yield return GetNeighbor((p.x, p.y - 1), cost + 1.004d); + } + + // Find the shortest path from start to end + var result = SuperEnumerable + .GetShortestPath<(int x, int y), double>( + start, + GetNeighbors, + end, + new PointComparer(), + null); + } + + private class PointComparer : IEqualityComparer<(int x, int y)> + { + public bool Equals((int x, int y) x, (int x, int y) y) => + ManhattanDistance(x) == ManhattanDistance(y); + + public int GetHashCode((int x, int y) obj) => + ManhattanDistance(obj).GetHashCode(); + + private static double ManhattanDistance((int x, int y) obj) => + Math.Sqrt((obj.x * obj.x) + (obj.y * obj.y)); + } + [Fact] public void InvalidMapThrowsException() { From 43cf9b0154ddfcabd696ad0d66ccb76f75cdd7bc Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 12 Oct 2023 16:19:48 -0500 Subject: [PATCH 043/124] Update documentation for `GetShortestPathCost` --- ...inq.SuperEnumerable.GetShortestPathCost.md | 55 ++++ .../GetShortestPathCost1.linq | 34 ++ .../GetShortestPathCost2.linq | 48 +++ .../GetShortestPathCost3.linq | 34 ++ .../GetShortestPathCost4.linq | 48 +++ .../GetShortestPathCost1.linq | 40 +++ .../GetShortestPathCost2.linq | 42 +++ .../GetShortestPathCost3.linq | 40 +++ .../GetShortestPathCost4.linq | 51 +++ .../SuperLinq/GetShortestPathCost.A-Star.cs | 295 ++++++++++-------- .../SuperLinq/GetShortestPathCost.Dijkstra.cs | 275 +++++++++------- 11 files changed, 712 insertions(+), 250 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPathCost.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPathCost.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPathCost.md new file mode 100644 index 00000000..0858f9ce --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPathCost.md @@ -0,0 +1,55 @@ +--- +uid: SuperLinq.SuperEnumerable.GetShortestPathCost``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1}}},``0) +example: [*content] +--- +The following code example demonstrates how to use Dijkstra's algorithm to find the shortest path to a destination using `GetShortestPathCost`. +[!code-csharp[](SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPathCost``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1}}},``0,System.Collections.Generic.IEqualityComparer{``0},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to use Dijkstra's algorithm to find the shortest path to a destination using `GetShortestPathCost`. +[!code-csharp[](SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPathCost``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1}}},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to use Dijkstra's algorithm to find the shortest path to a destination using `GetShortestPathCost`. +[!code-csharp[](SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPathCost``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1}}},System.Func{``0,System.Boolean},System.Collections.Generic.IEqualityComparer{``0},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to use Dijkstra's algorithm to find the shortest path to a destination using `GetShortestPathCost`. +[!code-csharp[](SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPathCost``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1,``1}}},``0) +example: [*content] +--- +The following code example demonstrates how to use A* to find the shortest path to a destination using `GetShortestPathCost`. +[!code-csharp[](SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPathCost``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1,``1}}},``0,System.Collections.Generic.IEqualityComparer{``0},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to use A* to find the shortest path to a destination using `GetShortestPathCost`. +[!code-csharp[](SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPathCost``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1,``1}}},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to use A* to find the shortest path to a destination using `GetShortestPathCost`. +[!code-csharp[](SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPathCost``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1,``1}}},System.Func{``0,System.Boolean},System.Collections.Generic.IEqualityComparer{``0},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to use A* to find the shortest path to a destination using `GetShortestPathCost`. +[!code-csharp[](SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost1.linq new file mode 100644 index 00000000..c92447f0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost1.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var start = (x: 0, y: 0); +var end = (x: 2, y: 2); +((int x, int y) p, double cost, double bestGuess) GetNeighbor((int x, int y) p, double newCost) +{ + var xD = p.x - end.x; + var yD = p.y - end.y; + var dist = Math.Sqrt((xD * xD) + (yD * yD)); + return (p, newCost, newCost + dist); +} + +IEnumerable<((int x, int y) p, double cost, double bestGuess)> GetNeighbors((int x, int y) p, double cost) +{ + yield return GetNeighbor((p.x + 1, p.y), cost + 1.001d); + yield return GetNeighbor((p.x, p.y + 1), cost + 1.002d); + yield return GetNeighbor((p.x - 1, p.y), cost + 1.003d); + yield return GetNeighbor((p.x, p.y - 1), cost + 1.004d); +} + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPathCost<(int x, int y), double>( + start, + GetNeighbors, + end); + +Console.WriteLine($"cost: {result:N3}"); + +// This code produces the following output: +// cost: 4.006 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost2.linq new file mode 100644 index 00000000..85b5cdc6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost2.linq @@ -0,0 +1,48 @@ + + SuperLinq + SuperLinq + + +var start = (x: 0, y: 0); +var end = (x: -2, y: -2); +((int x, int y) p, double cost, double bestGuess) GetNeighbor((int x, int y) p, double newCost) +{ + var xD = p.x - end.x; + var yD = p.y - end.y; + var dist = Math.Sqrt((xD * xD) + (yD * yD)); + return (p, newCost, newCost + dist); +} + +IEnumerable<((int x, int y) p, double cost, double bestGuess)> GetNeighbors((int x, int y) p, double cost) +{ + yield return GetNeighbor((p.x + 1, p.y), cost + 1.001d); + yield return GetNeighbor((p.x, p.y + 1), cost + 1.002d); + yield return GetNeighbor((p.x - 1, p.y), cost + 1.003d); + yield return GetNeighbor((p.x, p.y - 1), cost + 1.004d); +} + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPathCost<(int x, int y), double>( + start, + GetNeighbors, + end, + new PointComparer(), + null); + +Console.WriteLine($"cost: {result:N3}"); + +// This code produces the following output: +// cost: 4.014 + +class PointComparer : IEqualityComparer<(int x, int y)> +{ + public bool Equals((int x, int y) x, (int x, int y) y) => + ManhattanDistance(x) == ManhattanDistance(y); + + public int GetHashCode((int x, int y) obj) => + ManhattanDistance(obj).GetHashCode(); + + private static double ManhattanDistance((int x, int y) obj) => + Math.Sqrt((obj.x * obj.x) + (obj.y * obj.y)); +} \ No newline at end of file diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost3.linq new file mode 100644 index 00000000..ba0e7df5 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost3.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var start = (x: 0, y: 0); +var end = (x: 2, y: 2); +((int x, int y) p, double cost, double bestGuess) GetNeighbor((int x, int y) p, double newCost) +{ + var xD = p.x - end.x; + var yD = p.y - end.y; + var dist = Math.Sqrt((xD * xD) + (yD * yD)); + return (p, newCost, newCost + dist); +} + +IEnumerable<((int x, int y) p, double cost, double bestGuess)> GetNeighbors((int x, int y) p, double cost) +{ + yield return GetNeighbor((p.x + 1, p.y), cost + 1.001d); + yield return GetNeighbor((p.x, p.y + 1), cost + 1.002d); + yield return GetNeighbor((p.x - 1, p.y), cost + 1.003d); + yield return GetNeighbor((p.x, p.y - 1), cost + 1.004d); +} + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPathCost<(int x, int y), double>( + start, + GetNeighbors, + state => state == end); + +Console.WriteLine($"cost: {result:N3}"); + +// This code produces the following output: +// cost: 4.006 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost4.linq new file mode 100644 index 00000000..57186be7 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.AStar/GetShortestPathCost4.linq @@ -0,0 +1,48 @@ + + SuperLinq + SuperLinq + + +var start = (x: 0, y: 0); +var end = (x: -2, y: -2); +((int x, int y) p, double cost, double bestGuess) GetNeighbor((int x, int y) p, double newCost) +{ + var xD = p.x - end.x; + var yD = p.y - end.y; + var dist = Math.Sqrt((xD * xD) + (yD * yD)); + return (p, newCost, newCost + dist); +} + +IEnumerable<((int x, int y) p, double cost, double bestGuess)> GetNeighbors((int x, int y) p, double cost) +{ + yield return GetNeighbor((p.x + 1, p.y), cost + 1.001d); + yield return GetNeighbor((p.x, p.y + 1), cost + 1.002d); + yield return GetNeighbor((p.x - 1, p.y), cost + 1.003d); + yield return GetNeighbor((p.x, p.y - 1), cost + 1.004d); +} + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPathCost<(int x, int y), double>( + start, + GetNeighbors, + state => new PointComparer().Equals(state, end), + new PointComparer(), + null); + +Console.WriteLine($"cost: {result:N3}"); + +// This code produces the following output: +// cost: 4.014 + +class PointComparer : IEqualityComparer<(int x, int y)> +{ + public bool Equals((int x, int y) x, (int x, int y) y) => + ManhattanDistance(x) == ManhattanDistance(y); + + public int GetHashCode((int x, int y) obj) => + ManhattanDistance(obj).GetHashCode(); + + private static double ManhattanDistance((int x, int y) obj) => + Math.Sqrt((obj.x * obj.x) + (obj.y * obj.y)); +} \ No newline at end of file diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost1.linq new file mode 100644 index 00000000..205082ef --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost1.linq @@ -0,0 +1,40 @@ + + SuperLinq + SuperLinq + + +var costs = + new[] + { + (from: "start", to: "a", cost: 1), + (from: "a", to: "b", cost: 2), + (from: "b", to: "c", cost: 3), + (from: "c", to: "d", cost: 4), + (from: "d", to: "end", cost: 5), + (from: "start", to: "A", cost: 10), + (from: "A", to: "B", cost: 20), + (from: "B", to: "C", cost: 30), + (from: "C", to: "D", cost: 40), + (from: "D", to: "end", cost: 50), + (from: "start", to: "END", cost: 10), + (from: "start", to: "END", cost: 1000), + }; +var map = costs + .Concat(costs.Select(x => (from: x.to, to: x.from, x.cost))) + .Where(x => + x.to != "start" + && x.from != "end") + .ToLookup(x => x.from, x => (x.to, x.cost)); + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPathCost( + "start", + (state, cost) => map[state] + .Select(x => (x.to, x.cost + cost)), + "end"); + +Console.WriteLine($"cost: {result}"); + +// This code produces the following output: +// cost: 15 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost2.linq new file mode 100644 index 00000000..ff2f5b19 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost2.linq @@ -0,0 +1,42 @@ + + SuperLinq + SuperLinq + + +var costs = + new[] + { + (from: "start", to: "a", cost: 1), + (from: "a", to: "b", cost: 2), + (from: "b", to: "c", cost: 3), + (from: "c", to: "d", cost: 4), + (from: "d", to: "end", cost: 5), + (from: "start", to: "A", cost: 10), + (from: "A", to: "B", cost: 20), + (from: "B", to: "C", cost: 30), + (from: "C", to: "D", cost: 40), + (from: "D", to: "end", cost: 50), + (from: "start", to: "END", cost: 10), + (from: "start", to: "END", cost: 1000), + }; +var map = costs + .Concat(costs.Select(x => (from: x.to, to: x.from, x.cost))) + .Where(x => + x.to != "start" + && x.from != "end") + .ToLookup(x => x.from, x => (x.to, x.cost), StringComparer.OrdinalIgnoreCase); + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPathCost( + "start", + (state, cost) => map[state] + .Select(x => (x.to, x.cost + cost)), + "end", + StringComparer.OrdinalIgnoreCase, + default); + +Console.WriteLine($"cost: {result}"); + +// This code produces the following output: +// cost: 10 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost3.linq new file mode 100644 index 00000000..7b063a4e --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost3.linq @@ -0,0 +1,40 @@ + + SuperLinq + SuperLinq + + +var costs = + new[] + { + (from: (id: "start", index: 1), to: (id: "a", index: 2), cost: 1), + (from: (id: "a", index: 2), to: (id: "b", index: 3), cost: 2), + (from: (id: "b", index: 3), to: (id: "c", index: 3), cost: 3), + (from: (id: "c", index: 3), to: (id: "d", index: 4), cost: 4), + (from: (id: "d", index: 4), to: (id: "end", index: 5), cost: 5), + (from: (id: "start", index: 1), to: (id: "A", index: 6), cost: 10), + (from: (id: "A", index: 6), to: (id: "B", index: 7), cost: 20), + (from: (id: "B", index: 7), to: (id: "C", index: 8), cost: 30), + (from: (id: "C", index: 8), to: (id: "D", index: 9), cost: 40), + (from: (id: "D", index: 9), to: (id: "end", index: 5), cost: 50), + (from: (id: "start", index: 1), to: (id: "END", index: 10), cost: 10), + (from: (id: "start", index: 1), to: (id: "END", index: 10), cost: 1000), + }; +var map = costs + .Concat(costs.Select(x => (from: x.to, to: x.from, x.cost))) + .Where(x => + x.to.id != "start" + && x.from.id != "end") + .ToLookup(x => x.from.id, x => (x.to, x.cost)); + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPathCost<(string id, int index), int>( + ("start", 1), + (state, cost) => map[state.id] + .Select(x => (x.to, x.cost + cost)), + x => x.id == "end"); + +Console.WriteLine($"cost: {result}"); + +// This code produces the following output: +// cost: 15 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost4.linq new file mode 100644 index 00000000..6da8b15b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPathCost.Dijkstra/GetShortestPathCost4.linq @@ -0,0 +1,51 @@ + + SuperLinq + SuperLinq + + +var costs = + new[] + { + (from: (id: "start", index: 1), to: (id: "a", index: 2), cost: 1), + (from: (id: "a", index: 2), to: (id: "b", index: 3), cost: 2), + (from: (id: "b", index: 3), to: (id: "c", index: 3), cost: 3), + (from: (id: "c", index: 3), to: (id: "d", index: 4), cost: 4), + (from: (id: "d", index: 4), to: (id: "end", index: 5), cost: 5), + (from: (id: "start", index: 1), to: (id: "A", index: 6), cost: 10), + (from: (id: "A", index: 6), to: (id: "B", index: 7), cost: 20), + (from: (id: "B", index: 7), to: (id: "C", index: 8), cost: 30), + (from: (id: "C", index: 8), to: (id: "D", index: 9), cost: 40), + (from: (id: "D", index: 9), to: (id: "end", index: 5), cost: 50), + (from: (id: "start", index: 1), to: (id: "END", index: 10), cost: 10), + (from: (id: "start", index: 1), to: (id: "END", index: 10), cost: 1000), + }; +var map = costs + .Concat(costs.Select(x => (from: x.to, to: x.from, x.cost))) + .Where(x => + x.to.id != "start" + && x.from.id != "end") + .ToLookup(x => x.from.id, x => (x.to, x.cost), StringComparer.OrdinalIgnoreCase); + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPathCost<(string id, int index), int>( + ("start", 1), + (state, cost) => map[state.id] + .Select(x => (x.to, x.cost + cost)), + x => x.id.Equals("end", StringComparison.OrdinalIgnoreCase), + new StateComparer(), + default); + +Console.WriteLine($"cost: {result}"); + +// This code produces the following output: +// cost: 10 + +class StateComparer : IEqualityComparer<(string id, int index)> +{ + public bool Equals((string id, int index) x, (string id, int index) y) => + StringComparer.OrdinalIgnoreCase.Equals(x.id, y.id); + + public int GetHashCode((string id, int index) obj) => + StringComparer.OrdinalIgnoreCase.GetHashCode(obj.id); +} diff --git a/Source/SuperLinq/GetShortestPathCost.A-Star.cs b/Source/SuperLinq/GetShortestPathCost.A-Star.cs index 5d3567ce..4fa4ed55 100644 --- a/Source/SuperLinq/GetShortestPathCost.A-Star.cs +++ b/Source/SuperLinq/GetShortestPathCost.A-Star.cs @@ -5,62 +5,62 @@ namespace SuperLinq; public partial class SuperEnumerable { /// - /// Calculate the cost of the shortest path from - /// state to state , - /// using the A* algorithm. + /// Calculate the cost of the shortest path from state to state , + /// using the A* algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state; - /// the total cost to get to that state based on the - /// traversal cost at the current state; and the predicted - /// or best-guess total (already traversed plus remaining) - /// cost to get to . + /// A function that returns the neighbors for a given state; the total cost to get to that state based on the + /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus + /// remaining) cost to get to . + /// + /// + /// The target state /// - /// The target state /// - /// The traversal cost of the shortest path from - /// to . + /// The traversal cost of the shortest path from to . /// - /// is . - /// The map is entirely explored and no path to is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no path to is found. + /// /// /// - /// This method uses the A* algorithm to explore a map - /// and find the shortest path from - /// to . An - /// is used to manage the list of s - /// to process, to reduce the computation cost of this operator. - /// Overall performance of this method will depend on the reliability - /// of the best-guess cost provided by . + /// This method uses the A* algorithm to explore a map and find the shortest path from + /// to . An is used to manage + /// the list of s to process, to reduce the computation cost of this operator. + /// Overall performance of this method will depend on the reliability of the best-guess cost provided by + /// . /// /// - /// Loops and cycles are automatically detected and handled - /// correctly by this operator; only the cheapest path to - /// a given is used, and other - /// paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// The A* algorithm assumes that all costs are positive, - /// that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption - /// will have undefined behavior. + /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, - /// performance will depend on how many states are required to - /// be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This method uses - /// to compare s and - /// to compare traversal + /// This method uses to compare s and + /// to compare traversal /// s. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static TCost? GetShortestPathCost( @@ -79,58 +79,63 @@ public partial class SuperEnumerable } /// - /// Calculate the cost of the shortest path from - /// state to state , - /// using the A* algorithm. + /// Calculate the cost of the shortest path from state to state , + /// using the A* algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state; - /// the total cost to get to that state based on the - /// traversal cost at the current state; and the predicted - /// or best-guess total (already traversed plus remaining) - /// cost to get to . + /// A function that returns the neighbors for a given state; the total cost to get to that state based on the + /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus + /// remaining) cost to get to . + /// + /// + /// The target state + /// + /// + /// A custom equality comparer for + /// + /// + /// A custom comparer for /// - /// The target state - /// A custom equality comparer for - /// A custom comparer for /// - /// The traversal cost of the shortest path from - /// to . + /// The traversal cost of the shortest path from to . /// - /// is . - /// The map is entirely explored and no path to is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no path to is found. + /// /// /// - /// This method uses the A* algorithm to explore a map - /// and find the shortest path from - /// to . An - /// is used to manage the list of s - /// to process, to reduce the computation cost of this operator. - /// Overall performance of this method will depend on the reliability - /// of the best-guess cost provided by . + /// This method uses the A* algorithm to explore a map and find the shortest path from + /// to . An is used to manage + /// the list of s to process, to reduce the computation cost of this operator. + /// Overall performance of this method will depend on the reliability of the best-guess cost provided by + /// . /// /// - /// Loops and cycles are automatically detected and handled - /// correctly by this operator; only the cheapest path to - /// a given is used, and other - /// paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// The A* algorithm assumes that all costs are positive, - /// that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption - /// will have undefined behavior. + /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, - /// performance will depend on how many states are required to - /// be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static TCost? GetShortestPathCost( @@ -154,52 +159,64 @@ public partial class SuperEnumerable } /// - /// Calculate the cost of the shortest path from state to a state that satisfies the - /// conditions expressed by , using the A* algorithm. + /// Calculate the cost of the shortest path from state to a state that satisfies the + /// conditions expressed by , using the A* algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state; the total cost to get to that state based on the - /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus remaining) - /// cost to get to a state that satisfies the conditions expressed by . + /// A function that returns the neighbors for a given state; the total cost to get to that state based on the + /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus + /// remaining) cost to get to a state that satisfies the conditions expressed by . + /// + /// + /// The predicate that defines the conditions of the element to search for. /// - /// The predicate that defines the conditions of the element to search for. /// - /// The traversal cost of the shortest path from to a state that satisfies the conditions - /// expressed by . + /// The traversal cost of the shortest path from to a state that satisfies the + /// conditions expressed by . /// - /// is . - /// The map is entirely explored and no state that satisfies the - /// conditions expressed by is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no state that satisfies the conditions expressed by is found. + /// /// /// - /// This method uses the A* algorithm to explore a map and find the shortest path from to - /// a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. Overall performance of this - /// method will depend on the reliability of the best-guess cost provided by . + /// This method uses the A* algorithm to explore a map and find the shortest path from + /// to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. Overall performance of this + /// method will depend on the reliability of the best-guess cost provided by . /// /// - /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path to a - /// given is used, and other paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption will have undefined behavior. + /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, performance will depend on how many states are required - /// to be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This method uses to compare s and to compare traversal + /// This method uses to compare s and + /// to compare traversal /// s. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static TCost? GetShortestPathCost( @@ -218,49 +235,65 @@ public partial class SuperEnumerable } /// - /// Calculate the cost of the shortest path from state to a state that satisfies the - /// conditions expressed by , using the A* algorithm. + /// Calculate the cost of the shortest path from state to a state that satisfies the + /// conditions expressed by , using the A* algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state; the total cost to get to that state based on the - /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus remaining) - /// cost to get to a state that satisfies the conditions expressed by . + /// A function that returns the neighbors for a given state; the total cost to get to that state based on the + /// traversal cost at the current state; and the predicted or best-guess total (already traversed plus + /// remaining) cost to get to a state that satisfies the conditions expressed by . + /// + /// + /// The predicate that defines the conditions of the element to search for. + /// + /// + /// A custom equality comparer for + /// + /// + /// A custom comparer for /// - /// The predicate that defines the conditions of the element to search for. - /// A custom equality comparer for - /// A custom comparer for /// - /// The traversal cost of the shortest path from to a state that satisfies the conditions - /// expressed by . + /// The traversal cost of the shortest path from to a state that satisfies the + /// conditions expressed by . /// - /// is . - /// The map is entirely explored and no state that satisfies the - /// conditions expressed by is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no state that satisfies the conditions expressed by is found. + /// /// /// - /// This method uses the A* algorithm to explore a map and find the shortest path from to - /// a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. Overall performance of this - /// method will depend on the reliability of the best-guess cost provided by . + /// This method uses the A* algorithm to explore a map and find the shortest path from + /// to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. Overall performance of this + /// method will depend on the reliability of the best-guess cost provided by . /// /// - /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path to a - /// given is used, and other paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption will have undefined behavior. + /// The A* algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, performance will depend on how many states are required - /// to be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static TCost? GetShortestPathCost( diff --git a/Source/SuperLinq/GetShortestPathCost.Dijkstra.cs b/Source/SuperLinq/GetShortestPathCost.Dijkstra.cs index 058b552d..f667e545 100644 --- a/Source/SuperLinq/GetShortestPathCost.Dijkstra.cs +++ b/Source/SuperLinq/GetShortestPathCost.Dijkstra.cs @@ -5,58 +5,60 @@ namespace SuperLinq; public partial class SuperEnumerable { /// - /// Calculate the cost of the shortest path from - /// state to state , - /// using Dijkstra's algorithm. + /// Calculate the cost of the shortest path from state to state , + /// using Dijkstra's algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state - /// and the total cost to get to that state based on the - /// traversal cost at the current state. + /// A function that returns the neighbors for a given state and the total cost to get to that state based on the + /// traversal cost at the current state. /// - /// The target state + /// + /// The target state + /// /// - /// The traversal cost of the shortest path from - /// to . + /// The traversal cost of the shortest path from to . /// - /// is . - /// The map is entirely explored and no path to is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no path to is found. + /// /// /// - /// This method uses Dijkstra's algorithm to explore a map - /// and find the shortest path from - /// to . An - /// is used to manage the list of s - /// to process, to reduce the computation cost of this operator. + /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from to . An is + /// used to manage the list of s to process, to reduce the computation cost of this + /// operator. /// /// - /// Loops and cycles are automatically detected and handled - /// correctly by this operator; only the cheapest path to - /// a given is used, and other - /// paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// Dijkstra's algorithm assumes that all costs are positive, - /// that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption - /// will have undefined behavior. + /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, - /// performance will depend on how many states are required to - /// be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This method uses - /// to compare s and - /// to compare traversal + /// This method uses to compare s and + /// to compare traversal /// s. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static TCost? GetShortestPathCost( @@ -73,54 +75,61 @@ public partial class SuperEnumerable } /// - /// Calculate the cost of the shortest path from - /// state to state , - /// using Dijkstra's algorithm. + /// Calculate the cost of the shortest path from state to state , + /// using Dijkstra's algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state - /// and the total cost to get to that state based on the - /// traversal cost at the current state. + /// A function that returns the neighbors for a given state and the total cost to get to that state based on the + /// traversal cost at the current state. + /// + /// + /// The target state + /// + /// + /// A custom equality comparer for + /// + /// + /// A custom comparer for /// - /// The target state - /// A custom equality comparer for - /// A custom comparer for /// - /// The traversal cost of the shortest path from - /// to . + /// The traversal cost of the shortest path from to . /// - /// is . - /// The map is entirely explored and no path to is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no path to is found. + /// /// /// - /// This method uses Dijkstra's algorithm to explore a map - /// and find the shortest path from - /// to . An - /// is used to manage the list of s - /// to process, to reduce the computation cost of this operator. + /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from to . An is + /// used to manage the list of s to process, to reduce the computation cost of this + /// operator. /// /// - /// Loops and cycles are automatically detected and handled - /// correctly by this operator; only the cheapest path to - /// a given is used, and other - /// paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// Dijkstra's algorithm assumes that all costs are positive, - /// that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption - /// will have undefined behavior. + /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, - /// performance will depend on how many states are required to - /// be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static TCost? GetShortestPathCost( @@ -144,50 +153,62 @@ public partial class SuperEnumerable } /// - /// Calculate the cost of the shortest path from state to a state that satisfies the - /// conditions expressed by , using Dijkstra's algorithm. + /// Calculate the cost of the shortest path from state to a state that satisfies the + /// conditions expressed by , using Dijkstra's algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state and the total cost to get to that state based on the - /// traversal cost at the current state. + /// A function that returns the neighbors for a given state and the total cost to get to that state based on the + /// traversal cost at the current state. + /// + /// + /// The predicate that defines the conditions of the element to search for. /// - /// The predicate that defines the conditions of the element to search for. /// - /// The traversal cost of the shortest path from to a state that satisfies the conditions - /// expressed by . + /// The traversal cost of the shortest path from to a state that satisfies the + /// conditions expressed by . /// - /// is . - /// The map is entirely explored and no state that satisfies the - /// conditions expressed by is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no state that satisfies the conditions expressed by is found. + /// /// /// - /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from - /// to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. + /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. /// /// - /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path to a - /// given is used, and other paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a - /// negative distance from one state to the next. Violating this assumption will have undefined behavior. + /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, performance will depend on how many states are required - /// to be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This method uses to compare s and to compare traversal + /// This method uses to compare s and + /// to compare traversal /// s. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static TCost? GetShortestPathCost( @@ -204,47 +225,63 @@ public partial class SuperEnumerable } /// - /// Calculate the cost of the shortest path from state to a state that satisfies the - /// conditions expressed by , using Dijkstra's algorithm. + /// Calculate the cost of the shortest path from state to a state that satisfies the + /// conditions expressed by , using Dijkstra's algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state and the total cost to get to that state based on the - /// traversal cost at the current state. + /// A function that returns the neighbors for a given state and the total cost to get to that state based on the + /// traversal cost at the current state. + /// + /// + /// The predicate that defines the conditions of the element to search for. + /// + /// + /// A custom equality comparer for + /// + /// + /// A custom comparer for /// - /// The predicate that defines the conditions of the element to search for. - /// A custom equality comparer for - /// A custom comparer for /// - /// The traversal cost of the shortest path from to a state that satisfies the conditions - /// expressed by . + /// The traversal cost of the shortest path from to a state that satisfies the + /// conditions expressed by . /// - /// is . - /// The map is entirely explored and no state that satisfies the - /// conditions expressed by is found. + /// + /// is . + /// + /// + /// The map is entirely explored and no state that satisfies the conditions expressed by is found. + /// /// /// - /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from - /// to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. + /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from to a state that satisfies the conditions expressed by . An is used to manage the list of s to process, to reduce the computation cost of this operator. /// /// - /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path to a - /// given is used, and other paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a - /// negative distance from one state to the next. Violating this assumption will have undefined behavior. + /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method will operate on an infinite map, however, performance will depend on how many states are required - /// to be evaluated before reaching the target point. + /// This method will operate on an infinite map, however, performance will depend on how many states are + /// required to be evaluated before reaching the target point. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static TCost? GetShortestPathCost( From 6ddf1ce5db45600cc4b3208c33ce2303bde2c24a Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 12 Oct 2023 16:20:07 -0500 Subject: [PATCH 044/124] Update documentation for `GetShortestPaths` --- ...erLinq.SuperEnumerable.GetShortestPaths.md | 13 ++ .../GetShortestPaths/GetShortestPaths1.linq | 52 ++++++ .../GetShortestPaths/GetShortestPaths2.linq | 49 ++++++ Source/SuperLinq/GetShortestPaths.cs | 155 +++++++++--------- 4 files changed, 190 insertions(+), 79 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPaths.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPaths/GetShortestPaths1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPaths/GetShortestPaths2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPaths.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPaths.md new file mode 100644 index 00000000..1d2fd367 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GetShortestPaths.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.GetShortestPaths``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1}}}) +example: [*content] +--- +The following code example demonstrates how to use Dijkstra's algorithm to build a distance map using `GetShortestPaths`. +[!code-csharp[](SuperLinq/GetShortestPaths/GetShortestPaths1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GetShortestPaths``2(``0,System.Func{``0,``1,System.Collections.Generic.IEnumerable{System.ValueTuple{``0,``1}}},System.Collections.Generic.IEqualityComparer{``0},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to use Dijkstra's algorithm to build a distance map using `GetShortestPaths`. +[!code-csharp[](SuperLinq/GetShortestPaths/GetShortestPaths2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPaths/GetShortestPaths1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPaths/GetShortestPaths1.linq new file mode 100644 index 00000000..173effa1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPaths/GetShortestPaths1.linq @@ -0,0 +1,52 @@ + + SuperLinq + SuperLinq + + +var costs = + new[] + { + (from: "start", to: "a", cost: 1), + (from: "a", to: "b", cost: 2), + (from: "b", to: "c", cost: 3), + (from: "c", to: "d", cost: 4), + (from: "d", to: "end", cost: 5), + (from: "start", to: "A", cost: 10), + (from: "A", to: "B", cost: 20), + (from: "B", to: "C", cost: 30), + (from: "C", to: "D", cost: 40), + (from: "D", to: "end", cost: 50), + (from: "start", to: "END", cost: 10), + (from: "start", to: "END", cost: 1000), + }; +var map = costs + .Concat(costs.Select(x => (from: x.to, to: x.from, x.cost))) + .Where(x => + x.to != "start" + && x.from != "end") + .ToLookup(x => x.from, x => (x.to, x.cost)); + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPaths( + "start", + (state, cost) => map[state] + .Select(x => (x.to, x.cost + cost))); + +foreach (var (key, (from, cost)) in result) +{ + Console.WriteLine($"[{key}] = (from: {from}, totalCost: {cost})"); +} + +// This code produces the following output: +// [start] = (from: , totalCost: 0) +// [a] = (from: start, totalCost: 1) +// [b] = (from: a, totalCost: 3) +// [c] = (from: b, totalCost: 6) +// [END] = (from: start, totalCost: 10) +// [d] = (from: c, totalCost: 10) +// [A] = (from: start, totalCost: 10) +// [end] = (from: d, totalCost: 15) +// [B] = (from: A, totalCost: 30) +// [C] = (from: B, totalCost: 60) +// [D] = (from: C, totalCost: 100) diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPaths/GetShortestPaths2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPaths/GetShortestPaths2.linq new file mode 100644 index 00000000..90a30dbf --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GetShortestPaths/GetShortestPaths2.linq @@ -0,0 +1,49 @@ + + SuperLinq + SuperLinq + + +var costs = + new[] + { + (from: "start", to: "a", cost: 1), + (from: "a", to: "b", cost: 2), + (from: "b", to: "c", cost: 3), + (from: "c", to: "d", cost: 4), + (from: "d", to: "end", cost: 5), + (from: "start", to: "A", cost: 10), + (from: "A", to: "B", cost: 20), + (from: "B", to: "C", cost: 30), + (from: "C", to: "D", cost: 40), + (from: "D", to: "end", cost: 50), + (from: "start", to: "END", cost: 10), + (from: "start", to: "END", cost: 1000), + }; +var map = costs + .Concat(costs.Select(x => (from: x.to, to: x.from, x.cost))) + .Where(x => + x.to != "start" + && x.from != "end") + .ToLookup(x => x.from, x => (x.to, x.cost)); + +// Find the shortest path from start to end +var result = SuperEnumerable + .GetShortestPaths( + "start", + (state, cost) => map[state] + .Select(x => (x.to, x.cost + cost)), + StringComparer.OrdinalIgnoreCase, + default); + +foreach (var (key, (from, cost)) in result) +{ + Console.WriteLine($"[{key}] = (from: {from}, totalCost: {cost})"); +} + +// This code produces the following output: +// [start] = (from: , totalCost: 0) +// [a] = (from: start, totalCost: 1) +// [b] = (from: a, totalCost: 3) +// [c] = (from: b, totalCost: 6) +// [END] = (from: start, totalCost: 10) +// [d] = (from: c, totalCost: 10) diff --git a/Source/SuperLinq/GetShortestPaths.cs b/Source/SuperLinq/GetShortestPaths.cs index 0e8c26d3..4e678dca 100644 --- a/Source/SuperLinq/GetShortestPaths.cs +++ b/Source/SuperLinq/GetShortestPaths.cs @@ -5,64 +5,60 @@ namespace SuperLinq; public partial class SuperEnumerable { /// - /// Find the shortest path from state - /// to every other in the map, - /// using Dijkstra's algorithm. + /// Find the shortest path from state to every other in + /// the map, using Dijkstra's algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state - /// and the total cost to get to that state based on the - /// traversal cost at the current state. + /// A function that returns the neighbors for a given state and the total cost to get to that state based on the + /// traversal cost at the current state. /// /// - /// A map that contains, for every , - /// the previous in the shortest path - /// from to this , - /// as well as the total cost to travel from - /// to this . + /// A map that contains, for every , the previous in + /// the shortest path from to this , as well as the total + /// cost to travel from to this . /// - /// is . + /// + /// is . + /// /// /// - /// This method uses Dijkstra's algorithm to explore a map - /// and find the shortest path from - /// to every other in the map. - /// An - /// is used to manage the list of s - /// to process, to reduce the computation cost of this operator. + /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from to every other in the map. An is used to manage the list of s to process, to reduce the computation cost of this operator. /// /// - /// Loops and cycles are automatically detected and handled - /// correctly by this operator; only the cheapest path to - /// a given is used, and other - /// paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// While - /// and - /// will work work on infinite maps, this method - /// will execute an infinite loop on infinite maps. This is because - /// this method will attemp to visit every point in the map. - /// This method will terminate only when any points returned by - /// have all already been visited. + /// While and will work work on infinite maps, + /// this method will execute an infinite loop on infinite maps. This is because this method will attempt to + /// visit every point in the map. This method will terminate only when any points returned by have all already been visited. /// /// - /// Dijkstra's algorithm assumes that all costs are positive, - /// that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption - /// will have undefined behavior. + /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This method uses - /// to compare s and - /// to compare traversal + /// This method uses to compare s and + /// to compare traversal /// s. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static IReadOnlyDictionary @@ -80,60 +76,61 @@ public partial class SuperEnumerable } /// - /// Find the shortest path from state - /// to every other in the map, - /// using Dijkstra's algorithm. + /// Find the shortest path from state to every other in + /// the map, using Dijkstra's algorithm. /// - /// The type of each state in the map - /// The type of the cost to traverse between states - /// The starting state + /// + /// The type of each state in the map + /// + /// + /// The type of the cost to traverse between states + /// + /// + /// The starting state + /// /// - /// A function that returns the neighbors for a given state - /// and the total cost to get to that state based on the - /// traversal cost at the current state. + /// A function that returns the neighbors for a given state and the total cost to get to that state based on the + /// traversal cost at the current state. + /// + /// + /// A custom equality comparer for /// - /// A custom equality comparer for - /// A custom comparer for + /// + /// A custom comparer for + /// /// - /// A map that contains, for every , - /// the previous in the shortest path - /// from to this , - /// as well as the total cost to travel from - /// to this . + /// A map that contains, for every , the previous in + /// the shortest path from to this , as well as the total + /// cost to travel from to this . /// - /// is . + /// + /// is . + /// /// /// - /// This method uses Dijkstra's algorithm to explore a map - /// and find the shortest path from - /// to every other in the map. - /// An - /// is used to manage the list of s - /// to process, to reduce the computation cost of this operator. + /// This method uses Dijkstra's algorithm to explore a map and find the shortest path from to every other in the map. An is used to manage the list of s to process, to reduce the computation cost of this operator. /// /// - /// Loops and cycles are automatically detected and handled - /// correctly by this operator; only the cheapest path to - /// a given is used, and other - /// paths (including loops) are discarded. + /// Loops and cycles are automatically detected and handled correctly by this operator; only the cheapest path + /// to a given is used, and other paths (including loops) are discarded. /// /// - /// While - /// and - /// will work work on infinite maps, this method - /// will execute an infinite loop on infinite maps. This is because - /// this method will attemp to visit every point in the map. - /// This method will terminate only when any points returned by - /// have all already been visited. + /// While and will work work on infinite maps, + /// this method will execute an infinite loop on infinite maps. This is because this method will attempt to + /// visit every point in the map. This method will terminate only when any points returned by have all already been visited. /// /// - /// Dijkstra's algorithm assumes that all costs are positive, - /// that is to say, that it is not possible to go a negative - /// distance from one state to the next. Violating this assumption - /// will have undefined behavior. + /// Dijkstra's algorithm assumes that all costs are positive, that is to say, that it is not possible to go a + /// negative distance from one state to the next. Violating this assumption will have undefined behavior. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static IReadOnlyDictionary From a162aa6c9b192bafa3c9203379a621c534fc6be5 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 12 Oct 2023 17:14:15 -0500 Subject: [PATCH 045/124] Update documentation for `GroupAdjacent` --- ...SuperLinq.SuperEnumerable.GroupAdjacent.md | 41 +++ .../GroupAdjacent/GroupAdjacent1.linq | 35 ++ .../GroupAdjacent/GroupAdjacent2.linq | 36 ++ .../GroupAdjacent/GroupAdjacent3.linq | 36 ++ .../GroupAdjacent/GroupAdjacent4.linq | 37 ++ .../GroupAdjacent/GroupAdjacent5.linq | 36 ++ .../GroupAdjacent/GroupAdjacent6.linq | 37 ++ Source/SuperLinq/GroupAdjacent.cs | 330 ++++++++++-------- 8 files changed, 440 insertions(+), 148 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GroupAdjacent.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent5.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent6.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GroupAdjacent.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GroupAdjacent.md new file mode 100644 index 00000000..3baa98d4 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.GroupAdjacent.md @@ -0,0 +1,41 @@ +--- +uid: SuperLinq.SuperEnumerable.GroupAdjacent``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example shows how to group adjacent items in a sequence using `GroupAdjacent`: +[!code-csharp[](SuperLinq/GroupAdjacent/GroupAdjacent1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GroupAdjacent``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1}) +example: [*content] +--- +The following code example shows how to group adjacent items in a sequence using `GroupAdjacent`: +[!code-csharp[](SuperLinq/GroupAdjacent/GroupAdjacent2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GroupAdjacent``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``0,``2}) +example: [*content] +--- +The following code example shows how to group adjacent items in a sequence using `GroupAdjacent`: +[!code-csharp[](SuperLinq/GroupAdjacent/GroupAdjacent3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GroupAdjacent``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1}) +example: [*content] +--- +The following code example shows how to group adjacent items in a sequence using `GroupAdjacent`: +[!code-csharp[](SuperLinq/GroupAdjacent/GroupAdjacent4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GroupAdjacent``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``1,System.Collections.Generic.IEnumerable{``0},``2}) +example: [*content] +--- +The following code example shows how to group adjacent items in a sequence using `GroupAdjacent`: +[!code-csharp[](SuperLinq/GroupAdjacent/GroupAdjacent5.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.GroupAdjacent``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``1,System.Collections.Generic.IEnumerable{``0},``2},System.Collections.Generic.IEqualityComparer{``1}) +example: [*content] +--- +The following code example shows how to group adjacent items in a sequence using `GroupAdjacent`: +[!code-csharp[](SuperLinq/GroupAdjacent/GroupAdjacent6.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent1.linq new file mode 100644 index 00000000..2c137a4e --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent1.linq @@ -0,0 +1,35 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 1, value: 123), + (key: 1, value: 456), + (key: 1, value: 789), + (key: 2, value: 987), + (key: 2, value: 654), + (key: 2, value: 321), + (key: 3, value: 789), + (key: 3, value: 456), + (key: 3, value: 123), + (key: 1, value: 123), + (key: 1, value: 456), + (key: 1, value: 781), +}; + +// Group adjacent items +var result = sequence + .GroupAdjacent( + x => x.key); + +Console.WriteLine( + "[ " + + string.Join( + ", ", + result.Select(c => "[" + string.Join(", ", c) + "]")) + + " ]"); + +// This code produces the following output: +// [ [(1, 123), (1, 456), (1, 789)], [(2, 987), (2, 654), (2, 321)], [(3, 789), (3, 456), (3, 123)], [(1, 123), (1, 456), (1, 781)] ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent2.linq new file mode 100644 index 00000000..4b9f40cd --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent2.linq @@ -0,0 +1,36 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 789), + (key: "feb", value: 987), + (key: "Feb", value: 654), + (key: "FEB", value: 321), + (key: "mar", value: 789), + (key: "Mar", value: 456), + (key: "MAR", value: 123), + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 781), +}; + +// Group adjacent items +var result = sequence + .GroupAdjacent( + x => x.key, + StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[ " + + string.Join( + ", ", + result.Select(c => "[" + string.Join(", ", c) + "]")) + + " ]"); + +// This code produces the following output: +// [ [(jan, 123), (Jan, 456), (JAN, 789)], [(feb, 987), (Feb, 654), (FEB, 321)], [(mar, 789), (Mar, 456), (MAR, 123)], [(jan, 123), (Jan, 456), (JAN, 781)] ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent3.linq new file mode 100644 index 00000000..18e9749d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent3.linq @@ -0,0 +1,36 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 1, value: 123), + (key: 1, value: 456), + (key: 1, value: 789), + (key: 2, value: 987), + (key: 2, value: 654), + (key: 2, value: 321), + (key: 3, value: 789), + (key: 3, value: 456), + (key: 3, value: 123), + (key: 1, value: 123), + (key: 1, value: 456), + (key: 1, value: 781), +}; + +// Group adjacent items +var result = sequence + .GroupAdjacent( + x => x.key, + x => x.value); + +Console.WriteLine( + "[ " + + string.Join( + ", ", + result.Select(c => "[" + string.Join(", ", c) + "]")) + + " ]"); + +// This code produces the following output: +// [ [(1, 123), (1, 456), (1, 789)], [(2, 987), (2, 654), (2, 321)], [(3, 789), (3, 456), (3, 123)], [(1, 123), (1, 456), (1, 781)] ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent4.linq new file mode 100644 index 00000000..0e172e58 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent4.linq @@ -0,0 +1,37 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 789), + (key: "feb", value: 987), + (key: "Feb", value: 654), + (key: "FEB", value: 321), + (key: "mar", value: 789), + (key: "Mar", value: 456), + (key: "MAR", value: 123), + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 781), +}; + +// Group adjacent items +var result = sequence + .GroupAdjacent( + x => x.key, + x => x.value, + StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[ " + + string.Join( + ", ", + result.Select(c => "[" + string.Join(", ", c) + "]")) + + " ]"); + +// This code produces the following output: +// [ [123, 456, 789], [987, 654, 321], [789, 456, 123], [123, 456, 781] ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent5.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent5.linq new file mode 100644 index 00000000..e0eaed2d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent5.linq @@ -0,0 +1,36 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 1, value: 123), + (key: 1, value: 456), + (key: 1, value: 789), + (key: 2, value: 987), + (key: 2, value: 654), + (key: 2, value: 321), + (key: 3, value: 789), + (key: 3, value: 456), + (key: 3, value: 123), + (key: 1, value: 123), + (key: 1, value: 456), + (key: 1, value: 781), +}; + +// Group adjacent items +var result = sequence + .GroupAdjacent( + x => x.key, + (k, g) => new { Key = k, Items = "[" + string.Join(", ", g.Select(x => x.value)) + "]", }); + +Console.WriteLine( + "[ " + + string.Join( + ", ", + result) + + " ]"); + +// This code produces the following output: +// [ { Key = 1, Items = [123, 456, 789] }, { Key = 2, Items = [987, 654, 321] }, { Key = 3, Items = [789, 456, 123] }, { Key = 1, Items = [123, 456, 781] } ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent6.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent6.linq new file mode 100644 index 00000000..1ac065eb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/GroupAdjacent/GroupAdjacent6.linq @@ -0,0 +1,37 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 789), + (key: "feb", value: 987), + (key: "Feb", value: 654), + (key: "FEB", value: 321), + (key: "mar", value: 789), + (key: "Mar", value: 456), + (key: "MAR", value: 123), + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 781), +}; + +// Group adjacent items +var result = sequence + .GroupAdjacent( + x => x.key, + (k, g) => new { Key = k, Items = "[" + string.Join(", ", g.Select(x => x.value)) + "]", }, + StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[ " + + string.Join( + ", ", + result) + + " ]"); + +// This code produces the following output: +// [ { Key = jan, Items = [123, 456, 789] }, { Key = feb, Items = [987, 654, 321] }, { Key = mar, Items = [789, 456, 123] }, { Key = jan, Items = [123, 456, 781] } ] diff --git a/Source/SuperLinq/GroupAdjacent.cs b/Source/SuperLinq/GroupAdjacent.cs index 649a5101..42dbe1d8 100644 --- a/Source/SuperLinq/GroupAdjacent.cs +++ b/Source/SuperLinq/GroupAdjacent.cs @@ -5,27 +5,31 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Groups the adjacent elements of a sequence according to a - /// specified key selector function. + /// Groups the adjacent elements of a sequence according to a specified key selector function. /// - /// The type of the elements of - /// . - /// The type of the key returned by - /// . - /// A sequence whose elements to group. - /// A function to extract the key for each - /// element. - /// A sequence of groupings where each grouping - /// () contains the key - /// and the adjacent elements in the same order as found in the - /// source sequence. - /// is . - /// is . + /// + /// The type of the elements of . + /// + /// + /// The type of the key returned by . + /// + /// + /// A sequence whose elements to group. + /// + /// + /// A function to extract the key for each element. + /// + /// + /// A sequence of groupings where each grouping () contains the key and + /// the adjacent elements in the same order as found in the source sequence. + /// + /// + /// or is . + /// /// - /// This method is implemented by using deferred execution and - /// streams the groupings. The grouping elements, however, are - /// buffered. Each grouping is therefore yielded as soon as it - /// is complete and before the next grouping occurs. + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. /// public static IEnumerable> GroupAdjacent( this IEnumerable source, @@ -35,30 +39,35 @@ public static IEnumerable> GroupAdjacent } /// - /// Groups the adjacent elements of a sequence according to a - /// specified key selector function and compares the keys by using a - /// specified comparer. + /// Groups the adjacent elements of a sequence according to a specified key selector function and compares the + /// keys by using a specified comparer. /// - /// The type of the elements of - /// . - /// The type of the key returned by - /// . - /// A sequence whose elements to group. - /// A function to extract the key for each - /// element. - /// An to - /// compare keys. - /// A sequence of groupings where each grouping - /// () contains the key - /// and the adjacent elements in the same order as found in the - /// source sequence. - /// is . - /// is . + /// + /// The type of the elements of . + /// + /// + /// The type of the key returned by . + /// + /// + /// A sequence whose elements to group. + /// + /// + /// A function to extract the key for each element. + /// + /// + /// An to compare keys. + /// + /// + /// A sequence of groupings where each grouping () contains the key and + /// the adjacent elements in the same order as found in the source sequence. + /// + /// + /// or is . + /// /// - /// This method is implemented by using deferred execution and - /// streams the groupings. The grouping elements, however, are - /// buffered. Each grouping is therefore yielded as soon as it - /// is complete and before the next grouping occurs. + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. /// public static IEnumerable> GroupAdjacent( this IEnumerable source, @@ -72,33 +81,40 @@ public static IEnumerable> GroupAdjacent } /// - /// Groups the adjacent elements of a sequence according to a - /// specified key selector function and projects the elements for - /// each group by using a specified function. + /// Groups the adjacent elements of a sequence according to a specified key selector function and projects the + /// elements for each group by using a specified function. /// - /// The type of the elements of - /// . - /// The type of the key returned by - /// . - /// The type of the elements in the - /// resulting groupings. - /// A sequence whose elements to group. - /// A function to extract the key for each - /// element. - /// A function to map each source - /// element to an element in the resulting grouping. - /// A sequence of groupings where each grouping - /// () contains the key - /// and the adjacent elements (of type ) - /// in the same order as found in the source sequence. - /// is . - /// is . - /// is . + /// + /// The type of the elements of . + /// + /// + /// The type of the key returned by . + /// + /// + /// The type of the elements in the resulting groupings. + /// + /// + /// A sequence whose elements to group. + /// + /// + /// A function to extract the key for each element. + /// + /// + /// A function to map each source element to an element in the resulting grouping. + /// + /// + /// A sequence of groupings where each grouping () contains the key and + /// the adjacent elements (of type ) in the same order as found in the source + /// sequence. + /// + /// + /// , , or is . + /// /// - /// This method is implemented by using deferred execution and - /// streams the groupings. The grouping elements, however, are - /// buffered. Each grouping is therefore yielded as soon as it - /// is complete and before the next grouping occurs. + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. /// public static IEnumerable> GroupAdjacent( this IEnumerable source, @@ -116,36 +132,42 @@ public static IEnumerable> GroupAdjacent - /// Groups the adjacent elements of a sequence according to a - /// specified key selector function. The keys are compared by using - /// a comparer and each group's elements are projected by using a - /// specified function. + /// Groups the adjacent elements of a sequence according to a specified key selector function. The keys are + /// compared by using a comparer and each group's elements are projected by using a specified function. /// - /// The type of the elements of - /// . - /// The type of the key returned by - /// . - /// The type of the elements in the - /// resulting groupings. - /// A sequence whose elements to group. - /// A function to extract the key for each - /// element. - /// A function to map each source - /// element to an element in the resulting grouping. - /// An to - /// compare keys. - /// A sequence of groupings where each grouping - /// () contains the key - /// and the adjacent elements (of type ) - /// in the same order as found in the source sequence. - /// is . - /// is . - /// is . + /// + /// The type of the elements of . + /// + /// + /// The type of the key returned by . + /// + /// + /// The type of the elements in the resulting groupings. + /// + /// + /// A sequence whose elements to group. + /// + /// + /// A function to extract the key for each element. + /// + /// + /// A function to map each source element to an element in the resulting grouping. + /// + /// + /// An to compare keys. + /// + /// A sequence of groupings where each grouping () contains the key and + /// the adjacent elements (of type ) in the same order as found in the source + /// sequence. + /// + /// + /// , , or is . + /// /// - /// This method is implemented by using deferred execution and - /// streams the groupings. The grouping elements, however, are - /// buffered. Each grouping is therefore yielded as soon as it - /// is complete and before the next grouping occurs. + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. /// public static IEnumerable> GroupAdjacent( this IEnumerable source, @@ -164,33 +186,39 @@ public static IEnumerable> GroupAdjacent - /// Groups the adjacent elements of a sequence according to a - /// specified key selector function. The keys are compared by using - /// a comparer and each group's elements are projected by using a - /// specified function. + /// Groups the adjacent elements of a sequence according to a specified key selector function. The keys are + /// compared by using a comparer and each group's elements are projected by using a specified function. /// - /// The type of the elements of - /// . - /// The type of the key returned by - /// . - /// The type of the elements in the - /// resulting sequence. - /// A sequence whose elements to group. - /// A function to extract the key for each - /// element. - /// A function to map each key and - /// associated source elements to a result object. - /// A collection of elements of type - /// where each element represents - /// a projection over a group and its key. - /// is . - /// is . - /// is . + /// + /// The type of the elements of . + /// + /// + /// The type of the key returned by . + /// + /// + /// The type of the elements in the resulting sequence. + /// + /// + /// A sequence whose elements to group. + /// + /// + /// A function to extract the key for each element. + /// + /// + /// A function to map each key and associated source elements to a result object. + /// + /// + /// A collection of elements of type + /// where each element represents a projection over a group and its key. + /// + /// + /// , , or is . + /// /// - /// This method is implemented by using deferred execution and - /// streams the groupings. The grouping elements, however, are - /// buffered. Each grouping is therefore yielded as soon as it - /// is complete and before the next grouping occurs. + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. /// public static IEnumerable GroupAdjacent( this IEnumerable source, @@ -203,40 +231,46 @@ public static IEnumerable GroupAdjacent( return GroupAdjacentImpl( source, keySelector, Identity, - (key, group) => resultSelector(key, group), + resultSelector, comparer: null); } /// - /// Groups the adjacent elements of a sequence according to a - /// specified key selector function. The keys are compared by using - /// a comparer and each group's elements are projected by using a - /// specified function. + /// Groups the adjacent elements of a sequence according to a specified key selector function. The keys are + /// compared by using a comparer and each group's elements are projected by using a specified function. /// - /// The type of the elements of - /// . - /// The type of the key returned by - /// . - /// The type of the elements in the - /// resulting sequence. - /// A sequence whose elements to group. - /// A function to extract the key for each - /// element. - /// A function to map each key and - /// associated source elements to a result object. - /// An to - /// compare keys. - /// A collection of elements of type - /// where each element represents - /// a projection over a group and its key. - /// is . - /// is . - /// is . + /// + /// The type of the elements of . + /// + /// + /// The type of the key returned by . + /// + /// + /// The type of the elements in the resulting sequence. + /// + /// + /// A sequence whose elements to group. + /// + /// + /// A function to extract the key for each element. + /// + /// + /// A function to map each key and associated source elements to a result object. + /// + /// + /// An to compare keys. + /// + /// + /// A collection of elements of type + /// where each element represents a projection over a group and its key. + /// + /// , , or is . + /// /// - /// This method is implemented by using deferred execution and - /// streams the groupings. The grouping elements, however, are - /// buffered. Each grouping is therefore yielded as soon as it - /// is complete and before the next grouping occurs. + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. /// public static IEnumerable GroupAdjacent( this IEnumerable source, @@ -250,7 +284,7 @@ public static IEnumerable GroupAdjacent( return GroupAdjacentImpl( source, keySelector, Identity, - (key, group) => resultSelector(key, group), + resultSelector, comparer); } From a5530fcbf0fe2b2d0e739a92a3502110e3b929a4 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 13 Oct 2023 09:28:21 -0500 Subject: [PATCH 046/124] Update documentation for `HasDuplicates` --- ...SuperLinq.SuperEnumerable.HasDuplicates.md | 28 +++++ .../HasDuplicates/HasDuplicates1.linq | 26 ++++ .../HasDuplicates/HasDuplicates2.linq | 29 +++++ .../HasDuplicates/HasDuplicates3.linq | 29 +++++ .../HasDuplicates/HasDuplicates4.linq | 32 +++++ Source/SuperLinq/HasDuplicates.cs | 117 +++++++++++++----- 6 files changed, 232 insertions(+), 29 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.HasDuplicates.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.HasDuplicates.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.HasDuplicates.md new file mode 100644 index 00000000..6c52a101 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.HasDuplicates.md @@ -0,0 +1,28 @@ +--- +uid: SuperLinq.SuperEnumerable.HasDuplicates``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to check if a sequence has duplicate values using `HasDuplicates`. +[!code-csharp[](SuperLinq/HasDuplicates/HasDuplicates1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.HasDuplicates``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to check if a sequence has duplicate values using `HasDuplicates`. +[!code-csharp[](SuperLinq/HasDuplicates/HasDuplicates2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.HasDuplicates``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to check if a sequence has duplicate values using `HasDuplicates`. +[!code-csharp[](SuperLinq/HasDuplicates/HasDuplicates3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.HasDuplicates``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to check if a sequence has duplicate values using `HasDuplicates`. +[!code-csharp[](SuperLinq/HasDuplicates/HasDuplicates4.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates1.linq new file mode 100644 index 00000000..6873f5ff --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates1.linq @@ -0,0 +1,26 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "foo", "bar", "baz" }; +var seq2 = new[] { "foo", "bar", "baz", "foo", }; +var seq3 = new[] { "foo", "bar", "baz", "FOO", }; + +// determine if a sequence has duplicate items +var result = seq1 + .HasDuplicates(); +Console.WriteLine($"Has Duplicates: {result}"); + +result = seq2 + .HasDuplicates(); +Console.WriteLine($"Has Duplicates: {result}"); + +result = seq3 + .HasDuplicates(); +Console.WriteLine($"Has Duplicates: {result}"); + +// This code produces the following output: +// Has Duplicates: False +// Has Duplicates: True +// Has Duplicates: False diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates2.linq new file mode 100644 index 00000000..dec73a12 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates2.linq @@ -0,0 +1,29 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "foo", "bar", "baz" }; +var seq2 = new[] { "foo", "bar", "baz", "foo", }; +var seq3 = new[] { "foo", "bar", "baz", "FOO", }; + +// determine if a sequence has duplicate items +var result = seq1 + .HasDuplicates( + StringComparer.OrdinalIgnoreCase); +Console.WriteLine($"Has Duplicates: {result}"); + +result = seq2 + .HasDuplicates( + StringComparer.OrdinalIgnoreCase); +Console.WriteLine($"Has Duplicates: {result}"); + +result = seq3 + .HasDuplicates( + StringComparer.OrdinalIgnoreCase); +Console.WriteLine($"Has Duplicates: {result}"); + +// This code produces the following output: +// Has Duplicates: False +// Has Duplicates: True +// Has Duplicates: True diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates3.linq new file mode 100644 index 00000000..1a0836e0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates3.linq @@ -0,0 +1,29 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "f", "ba", "qax" }; +var seq2 = new[] { "f", "ba", "qax", "fuba", }; +var seq3 = new[] { "f", "ba", "qax", "FUBA", }; + +// determine if a sequence has duplicate items +var result = seq1 + .HasDuplicates( + x => x[0..1]); +Console.WriteLine($"Has Duplicates: {result}"); + +result = seq2 + .HasDuplicates( + x => x[0..1]); +Console.WriteLine($"Has Duplicates: {result}"); + +result = seq3 + .HasDuplicates( + x => x[0..1]); +Console.WriteLine($"Has Duplicates: {result}"); + +// This code produces the following output: +// Has Duplicates: False +// Has Duplicates: True +// Has Duplicates: False diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates4.linq new file mode 100644 index 00000000..5f1e0845 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/HasDuplicates/HasDuplicates4.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "f", "ba", "qax" }; +var seq2 = new[] { "f", "ba", "qax", "fuba", }; +var seq3 = new[] { "f", "ba", "qax", "FUBA", }; + +// determine if a sequence has duplicate items +var result = seq1 + .HasDuplicates( + x => x[0..1], + StringComparer.OrdinalIgnoreCase); +Console.WriteLine($"Has Duplicates: {result}"); + +result = seq2 + .HasDuplicates( + x => x[0..1], + StringComparer.OrdinalIgnoreCase); +Console.WriteLine($"Has Duplicates: {result}"); + +result = seq3 + .HasDuplicates( + x => x[0..1], + StringComparer.OrdinalIgnoreCase); +Console.WriteLine($"Has Duplicates: {result}"); + +// This code produces the following output: +// Has Duplicates: False +// Has Duplicates: True +// Has Duplicates: True diff --git a/Source/SuperLinq/HasDuplicates.cs b/Source/SuperLinq/HasDuplicates.cs index f47dc901..ac1fc205 100644 --- a/Source/SuperLinq/HasDuplicates.cs +++ b/Source/SuperLinq/HasDuplicates.cs @@ -3,69 +3,128 @@ public static partial class SuperEnumerable { /// - /// Checks if sequence contains duplicates + /// Checks if sequence contains duplicates. /// - /// The sequence to check. - /// The type of the elements in the source sequence + /// + /// The type of the elements in the source sequence. + /// + /// + /// The sequence to check. + /// + /// + /// is . + /// /// - /// if any element of the sequence is duplicated, - /// otherwise + /// if any element of the sequence is duplicated, otherwise. /// + /// + /// + /// This method executes immediately. + /// + /// public static bool HasDuplicates(this IEnumerable source) { return source.HasDuplicates(EqualityComparer.Default); } /// - /// Checks if sequence contains duplicates, using the specified element equality comparer + /// Checks if sequence contains duplicates, using the specified element equality comparer. /// - /// The sequence to check. + /// + /// The type of the elements in the source sequence. + /// + /// + /// The sequence to check. + /// /// - /// The equality comparer to use to determine whether or not keys are equal. - /// If null, the default equality comparer for TSource is used. + /// The equality comparer to use to determine whether or not keys are equal. If , the + /// default equality comparer for is used. /// - /// The type of the elements in the source sequence + /// + /// is . + /// /// - /// if any element of the sequence is duplicated, - /// otherwise + /// if any element of the sequence is duplicated, otherwise. /// + /// + /// + /// This method executes immediately. + /// + /// public static bool HasDuplicates(this IEnumerable source, IEqualityComparer? comparer) { return source.HasDuplicates(Identity, comparer); } /// - /// Checks if sequence contains duplicates, using the specified element equality comparer + /// Checks if sequence contains duplicates according to a specified key selector function. /// - /// The sequence to check. - /// Projection for determining "distinctness" - /// Type of the source sequence - /// Type of the projected element + /// + /// Type of the source sequence. + /// + /// + /// The type of key to distinguish elements by. + /// + /// + /// The sequence to check. + /// + /// + /// A function to extract the key for each element. + /// + /// + /// or is . + /// /// - /// if any element of the sequence is duplicated, - /// otherwise + /// if any element of the sequence is duplicated, otherwise. /// + /// + /// + /// This method executes immediately. + /// + /// public static bool HasDuplicates(this IEnumerable source, Func keySelector) { return source.HasDuplicates(keySelector, EqualityComparer.Default); } /// - /// Checks if sequence contains duplicates, using the specified element equality comparer + /// Checks if sequence contains duplicates according to a specified key selector function, using the specified + /// element equality comparer. /// - /// The sequence to check. - /// Projection for determining "distinctness" + /// + /// Type of the source sequence. + /// + /// + /// The type of key to distinguish elements by. + /// + /// + /// The sequence to check. + /// + /// + /// A function to extract the key for each element. + /// /// - /// The equality comparer to use to determine whether or not keys are equal. - /// If null, the default equality comparer for TSource is used. + /// The equality comparer to use to determine whether or not keys are equal. If , the + /// default equality comparer for is used. /// - /// Type of the source sequence - /// Type of the projected element + /// + /// or is . + /// /// - /// if any element of the sequence is duplicated, - /// otherwise + /// if any element of the sequence is duplicated, otherwise. /// - public static bool HasDuplicates(this IEnumerable source, Func keySelector, + /// + /// + /// This method executes immediately. + /// + /// + public static bool HasDuplicates( + this IEnumerable source, + Func keySelector, IEqualityComparer? comparer) { Guard.IsNotNull(source); From b8ddaa78a8bb38346f11204edf4ea9dc06727be5 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 13 Oct 2023 09:35:45 -0500 Subject: [PATCH 047/124] Update documentation for `If` --- .../apidoc/SuperLinq.SuperEnumerable.If.md | 13 ++++ .../apidoc/SuperLinq/If/If1.linq | 24 +++++++ .../apidoc/SuperLinq/If/If2.linq | 26 ++++++++ Source/SuperLinq/If.cs | 63 +++++++++++++------ 4 files changed, 106 insertions(+), 20 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.If.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/If/If1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/If/If2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.If.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.If.md new file mode 100644 index 00000000..168ef6f7 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.If.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.If``1(System.Func{System.Boolean},System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to selectively enumerate a sequence using `If`. +[!code-csharp[](SuperLinq/If/If1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.If``1(System.Func{System.Boolean},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to selectively enumerate a sequence using `If`. +[!code-csharp[](SuperLinq/If/If2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/If/If1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/If/If1.linq new file mode 100644 index 00000000..7b96bcbf --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/If/If1.linq @@ -0,0 +1,24 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// Use a function to select which sequence to return values from. +var selector = true; +var result = SuperEnumerable + .If( + () => selector, + sequence); + +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); +selector = false; +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); +selector = true; +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); + +// This code produces the following output: +// Selector: True; result.Count(): 5. +// Selector: False; result.Count(): 0. +// Selector: True; result.Count(): 5. diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/If/If2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/If/If2.linq new file mode 100644 index 00000000..c8d87c39 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/If/If2.linq @@ -0,0 +1,26 @@ + + SuperLinq + SuperLinq + + +var sequence1 = Enumerable.Range(1, 5); +var sequence2 = Enumerable.Range(1, 10); + +// Use a function to select which sequence to return values from. +var selector = true; +var result = SuperEnumerable + .If( + () => selector, + sequence1, + sequence2); + +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); +selector = false; +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); +selector = true; +Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}."); + +// This code produces the following output: +// Selector: True; result.Count(): 5. +// Selector: False; result.Count(): 10. +// Selector: True; result.Count(): 5. diff --git a/Source/SuperLinq/If.cs b/Source/SuperLinq/If.cs index ffb1f55d..d1662662 100644 --- a/Source/SuperLinq/If.cs +++ b/Source/SuperLinq/If.cs @@ -3,19 +3,28 @@ public static partial class SuperEnumerable { /// - /// Returns an enumerable sequence if the evaluation result of the given condition is , - /// otherwise returns an empty sequence. + /// Returns an enumerable sequence if the evaluation result of the given condition is , + /// otherwise returns an empty sequence. /// - /// Result sequence element type. - /// Condition to evaluate. - /// Sequence to return in case the condition evaluates true. - /// The given input sequence if the condition evaluates true; otherwise, an empty sequence. - /// or is . + /// + /// Result sequence element type. + /// + /// + /// Condition to evaluate. + /// + /// + /// Sequence to return in case the condition evaluates true. + /// + /// + /// The given input sequence if the condition evaluates ; otherwise, an empty sequence. + /// + /// + /// or is . + /// /// /// - /// is not evaluated until enumeration. If the value is , then - /// is enumerated. Otherwise, the sequence will be empty. + /// is not evaluated until enumeration. If the value is , + /// then is enumerated. Otherwise, the sequence will be empty. /// /// public static IEnumerable If(Func condition, IEnumerable thenSource) @@ -24,19 +33,33 @@ public static IEnumerable If(Func condition, IEnumerable } /// - /// Returns an enumerable sequence based on the evaluation result of the given condition. + /// Returns an enumerable sequence based on the evaluation result of the given condition. /// - /// Result sequence element type. - /// Condition to evaluate. - /// Sequence to return in case the condition evaluates . - /// Sequence to return in case the condition evaluates . - /// Either of the two input sequences based on the result of evaluating the condition. - /// , , or - /// is . + /// + /// Result sequence element type. + /// + /// + /// Condition to evaluate. + /// + /// + /// Sequence to return in case the condition evaluates . + /// + /// + /// Sequence to return in case the condition evaluates . + /// + /// + /// If the condition evaluates , then the sequence represented by ; otherwise the sequence represented by . + /// + /// + /// , , or is . + /// /// /// - /// is not evaluated until enumeration. If the value is , then - /// is enumerated. Otherwise, will be enumerated. + /// is not evaluated until enumeration. If the value is , + /// then is enumerated. Otherwise, will be + /// enumerated. /// /// public static IEnumerable If( From c040349b2604e27f6b178f5019bc477af1dcbdeb Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sun, 15 Oct 2023 17:04:04 -0500 Subject: [PATCH 048/124] Update documentation for `Index` --- .../apidoc/SuperLinq.SuperEnumerable.Index.md | 13 +++++ .../apidoc/SuperLinq/Index/Index1.linq | 23 ++++++++ .../apidoc/SuperLinq/Index/Index2.linq | 23 ++++++++ Source/SuperLinq/Index.cs | 57 ++++++++++++------- 4 files changed, 96 insertions(+), 20 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Index.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Index/Index1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Index/Index2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Index.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Index.md new file mode 100644 index 00000000..91aa63bd --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Index.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.Index``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to return an index with each element of a sequence using `Index`. +[!code-csharp[](SuperLinq/Index/Index1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Index``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to return an index with each element of a sequence using `Index`. +[!code-csharp[](SuperLinq/Index/Index2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Index/Index1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Index/Index1.linq new file mode 100644 index 00000000..7d7bdd91 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Index/Index1.linq @@ -0,0 +1,23 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 789), +}; + +// Index a sequence +var result = sequence + .Index(); + +Console.WriteLine( + "[ " + + string.Join(", ", result) + + " ]"); + +// This code produces the following output: +// [ (0, (jan, 123)), (1, (Jan, 456)), (2, (JAN, 789)) ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Index/Index2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Index/Index2.linq new file mode 100644 index 00000000..76e99f55 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Index/Index2.linq @@ -0,0 +1,23 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 789), +}; + +// Index a sequence +var result = sequence + .Index(5); + +Console.WriteLine( + "[ " + + string.Join(", ", result) + + " ]"); + +// This code produces the following output: +// [ (5, (jan, 123)), (6, (Jan, 456)), (7, (JAN, 789)) ] diff --git a/Source/SuperLinq/Index.cs b/Source/SuperLinq/Index.cs index a9ae34ca..a71d58b8 100644 --- a/Source/SuperLinq/Index.cs +++ b/Source/SuperLinq/Index.cs @@ -3,34 +3,51 @@ public static partial class SuperEnumerable { /// - /// Returns a sequence of tuples where the `key` is - /// the zero-based index of the `value` in the source - /// sequence. + /// Returns a sequence of tuples where the `index` is the zero-based index of the `item` in the sequence. /// - /// Type of elements in sequence. - /// The source sequence. - /// A sequence of tuples. - /// This operator uses deferred execution and streams its - /// results. - /// is . + /// + /// Type of elements in sequence. + /// + /// + /// The source sequence. + /// + /// + /// is . + /// + /// + /// A sequence of tuples. + /// + /// + /// This operator uses deferred execution and streams its results. + /// public static IEnumerable<(int index, TSource item)> Index(this IEnumerable source) { return source.Index(0); } /// - /// Returns a sequence of tuples where the `key` is - /// the zero-based index of the `value` in the source - /// sequence. An additional parameter specifies the - /// starting index. + /// Returns a sequence of tuples where the `index` is the -based index of the + /// `item` in the sequence. /// - /// Type of elements in sequence. - /// The source sequence. - /// - /// A sequence of tuples. - /// This operator uses deferred execution and streams its - /// results. - /// is . + /// + /// Type of elements in sequence. + /// + /// + /// The source sequence. + /// + /// + /// The index of the first value returned. + /// + /// + /// is . + /// + /// + /// A sequence of tuples. + /// + /// + /// This operator uses deferred execution and streams its results. + /// public static IEnumerable<(int index, TSource item)> Index(this IEnumerable source, int startIndex) { Guard.IsNotNull(source); From b341c811e08b6ca528168af7820a18064bebf68b Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sun, 15 Oct 2023 17:30:27 -0500 Subject: [PATCH 049/124] Update documentation for `IndexBy` --- .../SuperLinq.SuperEnumerable.IndexBy.md | 13 +++ .../apidoc/SuperLinq/IndexBy/IndexBy1.linq | 28 ++++++ .../apidoc/SuperLinq/IndexBy/IndexBy2.linq | 29 ++++++ Source/SuperLinq/IndexBy.cs | 97 +++++++++++++------ 4 files changed, 135 insertions(+), 32 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.IndexBy.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexBy/IndexBy1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexBy/IndexBy2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.IndexBy.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.IndexBy.md new file mode 100644 index 00000000..3f03e7f8 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.IndexBy.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.IndexBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to return a sub-sequence index with each element using `IndexBy`. +[!code-csharp[](SuperLinq/IndexBy/IndexBy1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.IndexBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to return a sub-sequence index with each element using `IndexBy`. +[!code-csharp[](SuperLinq/IndexBy/IndexBy2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexBy/IndexBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexBy/IndexBy1.linq new file mode 100644 index 00000000..f0caa692 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexBy/IndexBy1.linq @@ -0,0 +1,28 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + new { Key = 1, Value = 123, }, + new { Key = 2, Value = 987, }, + new { Key = 3, Value = 789, }, + new { Key = 1, Value = 123, }, + new { Key = 1, Value = 781, }, +}; + +// Group adjacent items +var result = sequence + .IndexBy( + x => x.Key); + +Console.WriteLine( + "[ " + + string.Join( + ", ", + result) + + " ]"); + +// This code produces the following output: +// [ (0, { Key = 1, Value = 123 }), (0, { Key = 2, Value = 987 }), (0, { Key = 3, Value = 789 }), (1, { Key = 1, Value = 123 }), (2, { Key = 1, Value = 781 }) ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexBy/IndexBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexBy/IndexBy2.linq new file mode 100644 index 00000000..c91b8391 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexBy/IndexBy2.linq @@ -0,0 +1,29 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + new { Key = "jan", Value = 123, }, + new { Key = "feb", Value = 987, }, + new { Key = "mar", Value = 789, }, + new { Key = "Jan", Value = 123, }, + new { Key = "JAN", Value = 781, }, +}; + +// Group adjacent items +var result = sequence + .IndexBy( + x => x.Key, + StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[ " + + string.Join( + ", ", + result) + + " ]"); + +// This code produces the following output: +// [ (0, { Key = jan, Value = 123 }), (0, { Key = feb, Value = 987 }), (0, { Key = mar, Value = 789 }), (1, { Key = Jan, Value = 123 }), (2, { Key = JAN, Value = 781 }) ] diff --git a/Source/SuperLinq/IndexBy.cs b/Source/SuperLinq/IndexBy.cs index 19dc3281..62c8da03 100644 --- a/Source/SuperLinq/IndexBy.cs +++ b/Source/SuperLinq/IndexBy.cs @@ -3,54 +3,87 @@ public static partial class SuperEnumerable { /// - /// Applies a key-generating function to each element of a sequence and - /// returns a sequence that contains the elements of the original - /// sequence as well its key and index inside the group of its key. + /// Applies a key-generating function to each element of a sequence and returns a sequence that contains the + /// elements of the original sequence as well its key and index inside the group of its key. /// - /// Type of the source sequence elements. - /// Type of the projected key. - /// Source sequence. + /// + /// Type of the source sequence elements. + /// + /// + /// Type of the projected key. + /// + /// + /// Source sequence. + /// /// - /// Function that projects the key given an element in the source sequence. + /// Function that projects the key given an element in the source sequence. + /// + /// + /// or is . + /// /// - /// A sequence of elements paired with their index within the key-group. - /// The index is the key and the element is the value of the pair. + /// A sequence of elements paired with their index within the key-group. The index is the key and the element is + /// the value of the pair. /// - /// is . - /// is . + /// + /// + /// This operator uses deferred execution and streams its results. + /// + /// public static IEnumerable<(int index, TSource item)> IndexBy( this IEnumerable source, - Func keySelector) => - source.IndexBy(keySelector, comparer: null); + Func keySelector) + { + return source.IndexBy(keySelector, comparer: null); + } /// - /// Applies a key-generating function to each element of a sequence and - /// returns a sequence that contains the elements of the original - /// sequence as well its key and index inside the group of its key. - /// An additional parameter specifies a comparer to use for testing the - /// equivalence of keys. + /// Applies a key-generating function to each element of a sequence and returns a sequence that contains the + /// elements of the original sequence as well its key and index inside the group of its key. An additional + /// parameter specifies a comparer to use for testing the equivalence of keys. /// - /// Type of the source sequence elements. - /// Type of the projected key. - /// Source sequence. + /// + /// Type of the source sequence elements. + /// + /// + /// Type of the projected key. + /// + /// + /// Source sequence. + /// /// - /// Function that projects the key given an element in the source sequence. + /// Function that projects the key given an element in the source sequence. + /// /// - /// The equality comparer to use to determine whether or not keys are - /// equal. If , the default equality comparer for - /// is used. + /// The equality comparer to use to determine whether or not keys are equal. If , the + /// default equality comparer for + /// is used. + /// + /// + /// or is . + /// /// - /// A sequence of elements paired with their index within the key-group. - /// The index is the key and the element is the value of the pair. + /// A sequence of elements paired with their index within the key-group. The index is the key and the element is + /// the value of the pair. /// - /// is . - /// is . + /// + /// + /// This operator uses deferred execution and streams its results. + /// + /// public static IEnumerable<(int index, TSource item)> IndexBy( this IEnumerable source, Func keySelector, - IEqualityComparer? comparer) => - from e in source.ScanBy(keySelector, k => (Index: -1, Item: default(TSource)), (s, k, e) => (s.Index + 1, e), comparer) - select (e.state.Index, e.state.Item); + IEqualityComparer? comparer) + { + return source + .ScanBy( + keySelector, + static k => (Index: -1, Item: default(TSource)!), + static (s, k, e) => (s.Index + 1, e), + comparer) + .Select(e => e.state); + } } From 22f1d6ccd65fb2989591a7517bc1afe337c1297d Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 20 Oct 2023 18:33:18 -0500 Subject: [PATCH 050/124] Update documentation for `IndexOf` --- .../SuperLinq.SuperEnumerable.IndexOf.md | 20 +++ .../apidoc/SuperLinq/IndexOf/IndexOf1.linq | 19 +++ .../apidoc/SuperLinq/IndexOf/IndexOf2.linq | 19 +++ .../apidoc/SuperLinq/IndexOf/IndexOf3.linq | 19 +++ Source/SuperLinq/IndexOf.cs | 127 +++++++++++------- 5 files changed, 155 insertions(+), 49 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.IndexOf.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.IndexOf.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.IndexOf.md new file mode 100644 index 00000000..252a2246 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.IndexOf.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.IndexOf``1(System.Collections.Generic.IEnumerable{``0},``0) +example: [*content] +--- +The following code example demonstrates how to find the index of an element in a sequence using `IndexOf`. +[!code-csharp[](SuperLinq/IndexOf/IndexOf1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.IndexOf``1(System.Collections.Generic.IEnumerable{``0},``0,System.Index) +example: [*content] +--- +The following code example demonstrates how to find the index of an element in a sequence using `IndexOf`. +[!code-csharp[](SuperLinq/IndexOf/IndexOf2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.IndexOf``1(System.Collections.Generic.IEnumerable{``0},``0,System.Index,System.Int32) +example: [*content] +--- +The following code example demonstrates how to find the index of an element in a sequence using `IndexOf`. +[!code-csharp[](SuperLinq/IndexOf/IndexOf3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf1.linq new file mode 100644 index 00000000..731ddb72 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf1.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + 1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, +}.AsEnumerable(); + +// Find the element `3` in the sequence +var result = sequence + .IndexOf(3); + +Console.WriteLine($"Index: {result}"); + +// This code produces the following output: +// Index: 2 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf2.linq new file mode 100644 index 00000000..05f16997 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf2.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + 1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, +}.AsEnumerable(); + +// Find the element `3` in the sequence in the range [5..] +var result = sequence + .IndexOf(3, 5); + +Console.WriteLine($"Index: {result}"); + +// This code produces the following output: +// Index: 7 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf3.linq new file mode 100644 index 00000000..dfcd29b0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/IndexOf/IndexOf3.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + 1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, +}.AsEnumerable(); + +// Find the element `3` in the sequence in the range [5..7] +var result = sequence + .IndexOf(3, 5, 2); + +Console.WriteLine($"Index: {result}"); + +// This code produces the following output: +// Index: -1 diff --git a/Source/SuperLinq/IndexOf.cs b/Source/SuperLinq/IndexOf.cs index f4f2f8f0..2ffca79c 100644 --- a/Source/SuperLinq/IndexOf.cs +++ b/Source/SuperLinq/IndexOf.cs @@ -3,30 +3,37 @@ public static partial class SuperEnumerable { /// - /// Searches for the specified object and returns the zero-based index of the first occurrence within the entire - /// . + /// Searches for the specified object and returns the zero-based index of the first occurrence within the entire + /// . /// /// - /// The type of elements of - /// The source sequence. - /// The object to locate in the . The value can be for reference types. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The object to locate in the . The value can be for + /// reference types. + /// /// - /// The zero-based index of the first occurrence of within the entire , if found; otherwise, -1. + /// The zero-based index of the first occurrence of within the entire , if found; otherwise, -1. /// - /// is null. + /// + /// is . + /// /// /// - /// The is searched forward starting at the first element and ending at the last - /// element. + /// The is searched forward starting at the first element and ending at the last + /// element. /// /// - /// This method determines equality using the default equality comparer - /// for , the type of values in the list. + /// This method determines equality using the default equality comparer for , the type of values in the list. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int IndexOf(this IEnumerable source, TSource item) @@ -35,32 +42,41 @@ public static int IndexOf(this IEnumerable source, TSource ite } /// - /// Searches for the specified object and returns the zero-based index of the first occurrence within the range of - /// elements in the that extends from the specified index to the last element. + /// Searches for the specified object and returns the zero-based index of the first occurrence within the range + /// of elements in the that extends from the specified index to the last element. /// /// - /// The type of elements of - /// The source sequence. - /// The object to locate in the . The value can be for reference types. - /// The of the starting element within the sequence. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The object to locate in the . The value can be for + /// reference types. + /// + /// + /// The of the starting element within the sequence. + /// /// - /// The zero-based index of the first occurrence of within the the range of elements in the - /// that extends from to the last element, if found; - /// otherwise, -1. + /// The zero-based index of the first occurrence of within the the range of elements in + /// the that extends from to the last element, if found; + /// otherwise, -1. /// - /// is null. + /// + /// is . + /// /// /// - /// The is searched forward starting at and ending at the last - /// element. + /// The is searched forward starting at and ending at the + /// last element. /// /// - /// This method determines equality using the default equality comparer - /// for , the type of values in the list. + /// This method determines equality using the default equality comparer for , the type of values in the list. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int IndexOf(this IEnumerable source, TSource item, Index index) @@ -69,35 +85,48 @@ public static int IndexOf(this IEnumerable source, TSource ite } /// - /// Searches for the specified object and returns the zero-based index of the first occurrence within the range of - /// elements in the that starts at the specified index to the last element and contains - /// the specified number of elements. + /// Searches for the specified object and returns the zero-based index of the first occurrence within the range + /// of elements in the that starts at the specified index to the last element and + /// contains the specified number of elements. /// /// - /// The type of elements of - /// The source sequence. - /// The object to locate in the . The value can be for reference types. - /// The of the starting element within the sequence. - /// The number of elements in the section to search. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The object to locate in the . The value can be for + /// reference types. + /// + /// + /// The of the starting element within the sequence. + /// + /// + /// The number of elements in the section to search. + /// /// - /// The zero-based index of the first occurrence of within the the range of elements in the - /// that that starts at and contains - /// number of elements, if found; otherwise, -1. + /// The zero-based index of the first occurrence of within the the range of elements in + /// the that that starts at and contains number of elements, if found; otherwise, -1. /// - /// is null. - /// is less than 0. + /// + /// is . + /// + /// + /// is less than 0. + /// /// /// - /// The is searched forward starting at and ending at - /// plus minus 1, if count is greater than 0. + /// The is searched forward starting at and ending at + /// plus minus 1, if count is greater than 0. /// /// - /// This method determines equality using the default equality comparer - /// for , the type of values in the list. + /// This method determines equality using the default equality comparer for , the type of values in the list. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int IndexOf(this IEnumerable source, TSource item, Index index, int count) From f59c194a25fa1b9469ed2f9407a916eda7e3f134 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 23 Oct 2023 08:58:55 -0500 Subject: [PATCH 051/124] Update documentation for `Insert` --- .../SuperLinq.SuperEnumerable.Insert.md | 13 +++ .../apidoc/SuperLinq/Insert/Insert1.linq | 16 ++++ .../apidoc/SuperLinq/Insert/Insert2.linq | 16 ++++ Source/SuperLinq/Insert.cs | 92 +++++++++++-------- 4 files changed, 99 insertions(+), 38 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Insert.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Insert/Insert1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Insert/Insert2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Insert.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Insert.md new file mode 100644 index 00000000..68c40b16 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Insert.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.Insert``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to insert one sequence into the middle of another sequence using `Insert`. +[!code-csharp[](SuperLinq/Insert/Insert1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Insert``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0},System.Index) +example: [*content] +--- +The following code example demonstrates how to insert one sequence into the middle of another sequence using `Insert`. +[!code-csharp[](SuperLinq/Insert/Insert2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Insert/Insert1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Insert/Insert1.linq new file mode 100644 index 00000000..a21dad67 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Insert/Insert1.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var first = Enumerable.Range(1, 5); +var second = Enumerable.Range(1, 5); + +// Insert one sequence into another +var result = first + .Insert(second, 2); + +Console.WriteLine(string.Join(", ", result)); + +// This code produces the following output: +// 1, 2, 1, 2, 3, 4, 5, 3, 4, 5 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Insert/Insert2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Insert/Insert2.linq new file mode 100644 index 00000000..e5d72f7f --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Insert/Insert2.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +var first = Enumerable.Range(1, 5); +var second = Enumerable.Range(1, 5); + +// Insert one sequence into another +var result = first + .Insert(second, ^2); + +Console.WriteLine(string.Join(", ", result)); + +// This code produces the following output: +// 1, 2, 3, 1, 2, 3, 4, 5, 4, 5 diff --git a/Source/SuperLinq/Insert.cs b/Source/SuperLinq/Insert.cs index 9a3169e7..673d2d2c 100644 --- a/Source/SuperLinq/Insert.cs +++ b/Source/SuperLinq/Insert.cs @@ -3,31 +3,39 @@ public static partial class SuperEnumerable { /// - /// Inserts the elements of a sequence into another sequence at a - /// specified index. + /// Inserts the elements of a sequence into another sequence at a specified index. /// - /// Type of the elements of the source sequence. - /// The source sequence. - /// The sequence that will be inserted. + /// + /// Type of the elements of the source sequence. + /// + /// + /// The source sequence. + /// + /// + /// The sequence that will be inserted. + /// /// - /// The zero-based index at which to insert elements from - /// . - /// - /// A sequence that contains the elements of - /// plus the elements of inserted at - /// the given index. - /// - /// is . - /// is . + /// The zero-based index at which to insert elements from . + /// + /// + /// or is . + /// /// - /// Thrown if is negative. + /// Thrown if is negative. /// /// - /// Thrown lazily if is greater than the - /// length of . The validation occurs when - /// yielding the next element after having iterated - /// entirely. + /// Thrown lazily if is greater than the length of . The + /// validation occurs when yielding the next element after having iterated entirely. /// + /// + /// A sequence that contains the elements of plus the elements of inserted at the given index. + /// + /// + /// + /// This method uses deferred execution and streams its results. + /// + /// public static IEnumerable Insert(this IEnumerable first, IEnumerable second, int index) { Guard.IsGreaterThanOrEqualTo(index, 0); @@ -36,31 +44,39 @@ public static IEnumerable Insert(this IEnumerable first, IEnumerable } /// - /// Inserts the elements of a sequence into another sequence at a - /// specified index. + /// Inserts the elements of a sequence into another sequence at a specified index. /// - /// Type of the elements of the source sequence. - /// The source sequence. - /// The sequence that will be inserted. + /// + /// Type of the elements of the source sequence. + /// + /// + /// The source sequence. + /// + /// + /// The sequence that will be inserted. + /// /// - /// The zero-based index at which to insert elements from - /// . - /// - /// A sequence that contains the elements of - /// plus the elements of inserted at - /// the given index. - /// - /// is . - /// is . + /// The zero-based index at which to insert elements from . + /// + /// + /// or is . + /// /// - /// Thrown if is negative. + /// Thrown if is negative. /// /// - /// Thrown lazily if is greater than the - /// length of . The validation occurs when - /// yielding the next element after having iterated - /// entirely. + /// Thrown lazily if is greater than the length of . The + /// validation occurs when yielding the next element after having iterated entirely. /// + /// + /// A sequence that contains the elements of plus the elements of inserted at the given index. + /// + /// + /// + /// This method uses deferred execution and streams its results. + /// + /// public static IEnumerable Insert(this IEnumerable first, IEnumerable second, Index index) { Guard.IsNotNull(first); From 1bdc8d0127237a1e1f2c84a7a0acd5cdd859d2ef Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 23 Oct 2023 09:17:36 -0500 Subject: [PATCH 052/124] Update documentation for `Interleave` --- .../SuperLinq.SuperEnumerable.Interleave.md | 13 ++++ .../SuperLinq/Interleave/Interleave1.linq | 17 +++++ .../SuperLinq/Interleave/Interleave2.linq | 17 +++++ Source/SuperLinq/Interleave.cs | 71 ++++++++++--------- 4 files changed, 85 insertions(+), 33 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Interleave.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Interleave/Interleave1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Interleave/Interleave2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Interleave.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Interleave.md new file mode 100644 index 00000000..c7db82ea --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Interleave.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.Interleave``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0}[]) +example: [*content] +--- +The following code example demonstrates how to interleave the elements from multiple sequences into a single sequence using `Interleave`. +[!code-csharp[](SuperLinq/Interleave/Interleave1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Interleave``1(System.Collections.Generic.IEnumerable{System.Collections.Generic.IEnumerable{``0}}) +example: [*content] +--- +The following code example demonstrates how to interleave the elements from multiple sequences into a single sequence using `Interleave`. +[!code-csharp[](SuperLinq/Interleave/Interleave2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Interleave/Interleave1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Interleave/Interleave1.linq new file mode 100644 index 00000000..c6a65eea --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Interleave/Interleave1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var seq1 = Enumerable.Range(1, 5); +var seq2 = Enumerable.Range(1, 4); +var seq3 = Enumerable.Range(1, 3); + +// Interleave the elements from multiple sequences into a single sequence +var result = seq1 + .Interleave(seq2, seq3); + +Console.WriteLine(string.Join(", ", result)); + +// This code produces the following output: +// 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Interleave/Interleave2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Interleave/Interleave2.linq new file mode 100644 index 00000000..88040225 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Interleave/Interleave2.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var seq1 = Enumerable.Range(1, 5); +var seq2 = Enumerable.Range(1, 4); +var seq3 = Enumerable.Range(1, 3); + +// Interleave the elements from multiple sequences into a single sequence +var result = new[] { seq1, seq2, seq3, } + .Interleave(); + +Console.WriteLine(string.Join(", ", result)); + +// This code produces the following output: +// 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5 diff --git a/Source/SuperLinq/Interleave.cs b/Source/SuperLinq/Interleave.cs index 586a0a46..d83b0a2e 100644 --- a/Source/SuperLinq/Interleave.cs +++ b/Source/SuperLinq/Interleave.cs @@ -5,27 +5,30 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Interleaves the elements of two or more sequences into a single sequence, skipping sequences as they are consumed + /// Interleaves the elements of two or more sequences into a single sequence in a round-robin fashion until all + /// sequences are consumed. /// + /// + /// The type of the elements of the source sequences + /// + /// + /// The first sequence in the interleave group + /// + /// + /// The other sequences in the interleave group + /// + /// + /// A sequence of interleaved elements from all of the source sequences + /// + /// + /// , , or any of the sequences in is . + /// /// - /// Interleave combines sequences by visiting each in turn, and returning the first element of each, followed - /// by the second, then the third, and so on. So, for example:
- /// { 1,2,3,1,2,3,1,2,3 } - /// ]]> - /// This operator behaves in a deferred and streaming manner.
- /// When sequences are of unequal length, this method will skip those sequences that have been fully consumed - /// and continue interleaving the remaining sequences.
- /// The sequences are interleaved in the order that they appear in the - /// collection, with as the first sequence. + /// + /// This method uses deferred execution and streams its results. + /// ///
- /// The type of the elements of the source sequences - /// The first sequence in the interleave group - /// The other sequences in the interleave group - /// A sequence of interleaved elements from all of the source sequences - /// is . - /// is . - /// Any of the items in is . public static IEnumerable Interleave(this IEnumerable source, params IEnumerable[] otherSources) { Guard.IsNotNull(source); @@ -41,24 +44,26 @@ public static IEnumerable Interleave(this IEnumerable source, params IE } /// - /// Interleaves the elements of two or more sequences into a single sequence, skipping sequences as they are consumed + /// Interleaves the elements of two or more sequences into a single sequence in a round-robin fashion until all + /// sequences are consumed. /// + /// + /// The type of the elements of the source sequences + /// + /// + /// The sequences to interleave together + /// + /// + /// A sequence of interleaved elements from all of the source sequences + /// + /// + /// is . + /// /// - /// Interleave combines sequences by visiting each in turn, and returning the first element of each, followed - /// by the second, then the third, and so on. So, for example:
- /// { 1,2,3,1,2,3,1,2,3 } - /// ]]> - /// This operator behaves in a deferred and streaming manner.
- /// When sequences are of unequal length, this method will skip those sequences that have been fully consumed - /// and continue interleaving the remaining sequences.
- /// The sequences are interleaved in the order that they appear in the - /// collection. + /// + /// This method uses deferred execution and streams its results. + /// ///
- /// The type of the elements of the source sequences - /// The sequences to interleave together - /// A sequence of interleaved elements from all of the source sequences - /// is . public static IEnumerable Interleave(this IEnumerable> sources) { Guard.IsNotNull(sources); From 0ecb084255e828563991668b3060c85145c0383c Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 25 Oct 2023 20:15:10 -0500 Subject: [PATCH 053/124] Update documentation for `Lag` --- .../apidoc/SuperLinq.SuperEnumerable.Lag.md | 20 +++ .../apidoc/SuperLinq/Lag/Lag1.linq | 17 +++ .../apidoc/SuperLinq/Lag/Lag2.linq | 17 +++ .../apidoc/SuperLinq/Lag/Lag3.linq | 17 +++ Source/SuperLinq/Lag.cs | 125 +++++++++++++----- 5 files changed, 163 insertions(+), 33 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Lag.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Lag.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Lag.md new file mode 100644 index 00000000..810a8ac3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Lag.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.Lag``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to get elements along with a previous value using `Lag`. +[!code-csharp[](SuperLinq/Lag/Lag1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Lag``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get elements along with a previous value using `Lag`. +[!code-csharp[](SuperLinq/Lag/Lag2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Lag``2(System.Collections.Generic.IEnumerable{``0},System.Int32,``0,System.Func{``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get elements along with a previous value using `Lag`. +[!code-csharp[](SuperLinq/Lag/Lag3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag1.linq new file mode 100644 index 00000000..f6939ab3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "baz" }; + +// get lagged elements +var result = sequence.Lag(1); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(foo, ), (bar, foo), (baz, bar)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag2.linq new file mode 100644 index 00000000..e742d9b0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag2.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "baz" }; + +// get lagged elements +var result = sequence.Lag(1, (cur, lag) => new { cur, lag, }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ cur = foo, lag = }, { cur = bar, lag = foo }, { cur = baz, lag = bar }] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag3.linq new file mode 100644 index 00000000..9ab25719 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lag/Lag3.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "baz" }; + +// get lagged elements +var result = sequence.Lag(1, "LAG", (cur, lag) => new { cur, lag, }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ cur = foo, lag = LAG }, { cur = bar, lag = foo }, { cur = baz, lag = bar }] diff --git a/Source/SuperLinq/Lag.cs b/Source/SuperLinq/Lag.cs index cab16ce9..e71957c8 100644 --- a/Source/SuperLinq/Lag.cs +++ b/Source/SuperLinq/Lag.cs @@ -3,17 +3,34 @@ public static partial class SuperEnumerable { /// - /// Produces a projection of a sequence by evaluating pairs of elements separated by a negative offset. + /// Produces a projection of a sequence by evaluating pairs of elements separated by a negative offset. /// - /// The type of the elements of the source sequence - /// The sequence over which to evaluate lag - /// The offset (expressed as a positive number) by which to lag each value of the sequence - /// A sequence of tuples with the current and lagged elements - /// is . - /// is below 1. + /// + /// The type of the elements of the source sequence + /// + /// + /// The sequence over which to evaluate lag + /// + /// + /// The offset (expressed as a positive number) by which to lag each value of the sequence + /// + /// + /// A sequence of tuples with the current and lagged elements + /// + /// + /// is . + /// + /// + /// is below 1. + /// /// - /// This operator evaluates in a deferred and streaming manner.
- /// For elements prior to the lag offset, (?) is used as the lagged value.
+ /// + /// For elements prior to the lag offset, (?) is + /// used as the lagged value.
+ ///
+ /// + /// This operator evaluates in a deferred and streaming manner. + /// ///
public static IEnumerable<(TSource current, TSource? lag)> Lag(this IEnumerable source, int offset) { @@ -21,20 +38,40 @@ public static partial class SuperEnumerable } /// - /// Produces a projection of a sequence by evaluating pairs of elements separated by a negative offset. + /// Produces a projection of a sequence by evaluating pairs of elements separated by a negative offset. /// - /// The type of the elements of the source sequence - /// The type of the elements of the result sequence - /// The sequence over which to evaluate lag - /// The offset (expressed as a positive number) by which to lag each value of the sequence - /// A projection function which accepts the current and lagged items (in that order) and returns a result - /// A sequence produced by projecting each element of the sequence with its lagged pairing - /// is . - /// is . - /// is below 1. + /// + /// The type of the elements of the source sequence + /// + /// + /// The type of the elements of the result sequence + /// + /// + /// The sequence over which to evaluate lag + /// + /// + /// The offset (expressed as a positive number) by which to lag each value of the sequence + /// + /// + /// A projection function which accepts the current and lagged items (in that order) and returns a result + /// + /// + /// A sequence produced by projecting each element of the sequence with its lagged pairing + /// + /// + /// or is . + /// + /// + /// is below 1. + /// /// - /// This operator evaluates in a deferred and streaming manner.
- /// For elements prior to the lag offset, (?) is used as the lagged value.
+ /// + /// For elements prior to the lag offset, (?) is + /// used as the lagged value.
+ ///
+ /// + /// This operator evaluates in a deferred and streaming manner. + /// ///
public static IEnumerable Lag(this IEnumerable source, int offset, Func resultSelector) { @@ -42,20 +79,42 @@ public static IEnumerable Lag(this IEnumerable - /// Produces a projection of a sequence by evaluating pairs of elements separated by a negative offset. + /// Produces a projection of a sequence by evaluating pairs of elements separated by a negative offset. /// - /// The type of the elements of the source sequence - /// The type of the elements of the result sequence - /// The sequence over which to evaluate lag - /// The offset (expressed as a positive number) by which to lag each value of the sequence - /// A default value supplied for the lagged value prior to the lag offset - /// A projection function which accepts the current and lagged items (in that order) and returns a result - /// A sequence produced by projecting each element of the sequence with its lagged pairing - /// is . - /// is . - /// is below 1. + /// + /// The type of the elements of the source sequence + /// + /// + /// The type of the elements of the result sequence + /// + /// + /// The sequence over which to evaluate lag + /// + /// + /// The offset (expressed as a positive number) by which to lag each value of the sequence + /// + /// + /// A default value supplied for the lagged value prior to the lag offset + /// + /// + /// A projection function which accepts the current and lagged items (in that order) and returns a result + /// + /// + /// A sequence produced by projecting each element of the sequence with its lagged pairing + /// + /// + /// or is . + /// + /// + /// is below 1. + /// /// - /// This operator evaluates in a deferred and streaming manner.
+ /// + /// For elements prior to the lag offset, is used as the lagged value.
+ ///
+ /// + /// This operator evaluates in a deferred and streaming manner. + /// ///
public static IEnumerable Lag(this IEnumerable source, int offset, TSource defaultLagValue, Func resultSelector) { From aab092696d715c84bfd006f12bb353060ee6d35a Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 27 Oct 2023 10:26:30 -0500 Subject: [PATCH 054/124] Update documentation for `LastIndexOf` --- .../SuperLinq.SuperEnumerable.LastIndexOf.md | 20 +++ .../SuperLinq/LastIndexOf/LastIndexOf1.linq | 19 +++ .../SuperLinq/LastIndexOf/LastIndexOf2.linq | 19 +++ .../SuperLinq/LastIndexOf/LastIndexOf3.linq | 19 +++ Source/SuperLinq/LastIndexOf.cs | 131 +++++++++++------- 5 files changed, 157 insertions(+), 51 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.LastIndexOf.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.LastIndexOf.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.LastIndexOf.md new file mode 100644 index 00000000..4f2cddea --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.LastIndexOf.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.LastIndexOf``1(System.Collections.Generic.IEnumerable{``0},``0) +example: [*content] +--- +The following code example demonstrates how to find the index of the last instance of an element in a sequence using `LastIndexOf`. +[!code-csharp[](SuperLinq/LastIndexOf/LastIndexOf1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.LastIndexOf``1(System.Collections.Generic.IEnumerable{``0},``0,System.LastIndex) +example: [*content] +--- +The following code example demonstrates how to find the index of the last instance of an element in a sequence using `LastIndexOf`. +[!code-csharp[](SuperLinq/LastIndexOf/LastIndexOf2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.LastIndexOf``1(System.Collections.Generic.IEnumerable{``0},``0,System.LastIndex,System.Int32) +example: [*content] +--- +The following code example demonstrates how to find the index of the last instance of an element in a sequence using `LastIndexOf`. +[!code-csharp[](SuperLinq/LastIndexOf/LastIndexOf3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf1.linq new file mode 100644 index 00000000..e33a4eb4 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf1.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + 1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, +}.AsEnumerable(); + +// Find the element `3` in the sequence +var result = sequence + .LastIndexOf(3); + +Console.WriteLine($"Index: {result}"); + +// This code produces the following output: +// Index: 7 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf2.linq new file mode 100644 index 00000000..483e4dfa --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf2.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + 1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, +}.AsEnumerable(); + +// Find the element `3` in the sequence in the range [5..] +var result = sequence + .LastIndexOf(3, 5); + +Console.WriteLine($"Index: {result}"); + +// This code produces the following output: +// Index: 7 diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf3.linq new file mode 100644 index 00000000..a959f1e7 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/LastIndexOf/LastIndexOf3.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + 1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, +}.AsEnumerable(); + +// Find the element `3` in the sequence in the range [0..3] +var result = sequence + .IndexOf(3, 0, 3); + +Console.WriteLine($"Index: {result}"); + +// This code produces the following output: +// Index: 2 diff --git a/Source/SuperLinq/LastIndexOf.cs b/Source/SuperLinq/LastIndexOf.cs index 10766540..9441a00a 100644 --- a/Source/SuperLinq/LastIndexOf.cs +++ b/Source/SuperLinq/LastIndexOf.cs @@ -3,30 +3,37 @@ public static partial class SuperEnumerable { /// - /// Searches for the specified object and returns the zero-based index of the last occurrence within the entire . + /// Searches for the specified object and returns the zero-based index of the last occurrence within the entire + /// . /// /// - /// The type of elements of - /// The source sequence. - /// The object to locate in the . The value can be for reference types. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The object to locate in the . The value can be for + /// reference types. + /// /// - /// The zero-based index of the last occurrence of within the entire , if found; otherwise, -1. + /// The zero-based index of the last occurrence of within the entire , if found; otherwise, -1. /// - /// is null. + /// + /// is . + /// /// /// - /// The is searched forward starting at the first element and ending at the last - /// element, and the index of the last instance of is returned. + /// The is searched forward starting at the first element and ending at the last + /// element, and the index of the last instance of is returned. /// /// - /// This method determines equality using the default equality comparer - /// for , the type of values in the list. + /// This method determines equality using the default equality comparer for , the type of values in the list. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int LastIndexOf(this IEnumerable source, TSource item) @@ -35,33 +42,42 @@ public static int LastIndexOf(this IEnumerable source, TSource } /// - /// Searches for the specified object and returns the zero-based index of the last occurrence within the range of - /// elements in the that extends backwards from the specified index to the first - /// element. + /// Searches for the specified object and returns the zero-based index of the last occurrence within the range + /// of elements in the that extends backwards from the specified index to the first + /// element. /// /// - /// The type of elements of - /// The source sequence. - /// The object to locate in the . The value can be for reference types. - /// The of the ending element within the sequence. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The object to locate in the . The value can be for + /// reference types. + /// + /// + /// The of the ending element within the sequence. + /// /// - /// The zero-based index of the last occurrence of within the the range of elements in the - /// that extends backwards from to the first element, if - /// found; otherwise, -1. + /// The zero-based index of the last occurrence of within the the range of elements in + /// the that extends backwards from to the first element, + /// if found; otherwise, -1. /// - /// is null. + /// + /// is . + /// /// /// - /// The is searched forward starting at the first element and ending at , and the index of the last instance of is returned. + /// The is searched forward starting at the first element and ending at , and the index of the last instance of is returned. /// /// - /// This method determines equality using the default equality comparer - /// for , the type of values in the list. + /// This method determines equality using the default equality comparer for , the type of values in the list. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int LastIndexOf(this IEnumerable source, TSource item, Index index) @@ -70,36 +86,49 @@ public static int LastIndexOf(this IEnumerable source, TSource } /// - /// Searches for the specified object and returns the zero-based index of the last occurrence within the range of - /// elements in the that ends at the specified index to the last element and contains - /// the specified number of elements. + /// Searches for the specified object and returns the zero-based index of the last occurrence within the range + /// of elements in the that ends at the specified index to the last element and + /// contains the specified number of elements. /// /// - /// The type of elements of - /// The source sequence. - /// The object to locate in the . The value can be for reference types. - /// The of the ending element within the sequence. - /// The number of elements in the section to search. + /// The type of elements of + /// + /// + /// The source sequence. + /// + /// + /// The object to locate in the . The value can be for + /// reference types. + /// + /// + /// The of the ending element within the sequence. + /// + /// + /// The number of elements in the section to search. + /// /// - /// The zero-based index of the last occurrence of within the the range of elements in the - /// that that ends at and contains - /// number of elements, if found; otherwise, -1. + /// The zero-based index of the last occurrence of within the the range of elements in + /// the that that ends at and contains number of elements, if found; otherwise, -1. /// - /// is null. - /// is less than 0. + /// + /// is . + /// + /// + /// is less than 0. + /// /// /// - /// The is searched forward starting at the first element and ending at , and the index of the last instance of no earlier in the sequence than - /// items before is returned. + /// The is searched forward starting at the first element and ending at , and the index of the last instance of no earlier in the sequence + /// than items before is returned. /// /// - /// This method determines equality using the default equality comparer - /// for , the type of values in the list. + /// This method determines equality using the default equality comparer for , the type of values in the list. /// /// - /// This operator executes immediately. + /// This operator executes immediately. /// /// public static int LastIndexOf(this IEnumerable source, TSource item, Index index, int count) From c40d4b70fd739f2b1088a5b621e3d52827aa09b8 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 27 Oct 2023 11:03:08 -0500 Subject: [PATCH 055/124] Update documentation for `Lead` --- .../apidoc/SuperLinq.SuperEnumerable.Lead.md | 20 +++ .../apidoc/SuperLinq/Lead/Lead1.linq | 17 +++ .../apidoc/SuperLinq/Lead/Lead2.linq | 17 +++ .../apidoc/SuperLinq/Lead/Lead3.linq | 17 +++ Source/SuperLinq/Lead.cs | 130 +++++++++++++----- 5 files changed, 163 insertions(+), 38 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Lead.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Lead.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Lead.md new file mode 100644 index 00000000..7e470daa --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Lead.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.Lead``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to get elements along with a future value using `Lead`. +[!code-csharp[](SuperLinq/Lead/Lead1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Lead``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get elements along with a future value using `Lead`. +[!code-csharp[](SuperLinq/Lead/Lead2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Lead``2(System.Collections.Generic.IEnumerable{``0},System.Int32,``0,System.Func{``0,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get elements along with a future value using `Lead`. +[!code-csharp[](SuperLinq/Lead/Lead3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead1.linq new file mode 100644 index 00000000..cb3db754 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "baz" }; + +// get leading elements +var result = sequence.Lead(1); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(foo, bar), (bar, baz), (baz, )] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead2.linq new file mode 100644 index 00000000..137d33c5 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead2.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "baz" }; + +// get leading elements +var result = sequence.Lead(1, (cur, lead) => new { cur, lead, }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ cur = foo, lead = bar }, { cur = bar, lead = baz }, { cur = baz, lead = }] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead3.linq new file mode 100644 index 00000000..c12de18b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Lead/Lead3.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "baz" }; + +// get leading elements +var result = sequence.Lead(1, "LEAD", (cur, lag) => new { cur, lag, }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ cur = foo, lag = bar }, { cur = bar, lag = baz }, { cur = baz, lag = LEAD }] diff --git a/Source/SuperLinq/Lead.cs b/Source/SuperLinq/Lead.cs index 02358c1b..c9ab91d0 100644 --- a/Source/SuperLinq/Lead.cs +++ b/Source/SuperLinq/Lead.cs @@ -3,18 +3,34 @@ public static partial class SuperEnumerable { /// - /// Produces a projection of a sequence by evaluating pairs of elements separated by a positive offset. + /// Produces a projection of a sequence by evaluating pairs of elements separated by a positive offset. /// - /// The type of the elements in the source sequence - /// The sequence over which to evaluate Lead - /// The offset (expressed as a positive number) by which to lead each element of the sequence - /// A sequence of tuples with the current and lead elements - /// is . - /// is below 1. + /// + /// The type of the elements in the source sequence + /// + /// + /// The sequence over which to evaluate Lead + /// + /// + /// The offset (expressed as a positive number) by which to lead each element of the sequence + /// + /// + /// A sequence of tuples with the current and lead elements + /// + /// + /// is . + /// + /// + /// is below 1. + /// /// - /// This operator evaluates in a deferred and streaming manner.
- /// For elements of the sequence that are less than items from the end, - /// (?) is used as the lead value.
+ /// + /// For elements of the sequence that are less than items from the end, (?) is used as the lead value.
+ ///
+ /// + /// This operator evaluates in a deferred and streaming manner. + /// ///
public static IEnumerable<(TSource current, TSource? lead)> Lead(this IEnumerable source, int offset) { @@ -22,21 +38,40 @@ public static partial class SuperEnumerable } /// - /// Produces a projection of a sequence by evaluating pairs of elements separated by a positive offset. + /// Produces a projection of a sequence by evaluating pairs of elements separated by a positive offset. /// - /// The type of the elements in the source sequence - /// The type of the elements in the result sequence - /// The sequence over which to evaluate Lead - /// The offset (expressed as a positive number) by which to lead each element of the sequence - /// A projection function which accepts the current and subsequent (lead) element (in that order) and produces a result - /// A sequence produced by projecting each element of the sequence with its lead pairing - /// is . - /// is . - /// is below 1. + /// + /// The type of the elements in the source sequence + /// + /// + /// The type of the elements in the result sequence + /// + /// + /// The sequence over which to evaluate Lead + /// + /// + /// The offset (expressed as a positive number) by which to lead each element of the sequence + /// + /// + /// A projection function which accepts the current and subsequent (lead) element (in that order) and produces a result + /// + /// + /// A sequence produced by projecting each element of the sequence with its lead pairing + /// + /// + /// or is . + /// + /// + /// is below 1. + /// /// - /// This operator evaluates in a deferred and streaming manner.
- /// For elements of the sequence that are less than items from the end, - /// (?) is used as the lead value.
+ /// + /// For elements of the sequence that are less than items from the end, (?) is used as the lead value.
+ ///
+ /// + /// This operator evaluates in a deferred and streaming manner. + /// ///
public static IEnumerable Lead(this IEnumerable source, int offset, Func resultSelector) { @@ -44,23 +79,42 @@ public static IEnumerable Lead(this IEnumerable - /// Produces a projection of a sequence by evaluating pairs of elements separated by a positive offset. + /// Produces a projection of a sequence by evaluating pairs of elements separated by a positive offset. /// + /// + /// The type of the elements in the source sequence + /// + /// + /// The type of the elements in the result sequence + /// + /// + /// The sequence over which to evaluate Lead + /// + /// + /// The offset (expressed as a positive number) by which to lead each element of the sequence + /// + /// + /// A default value supplied for the leading element when none is available + /// + /// + /// A projection function which accepts the current and subsequent (lead) element (in that order) and produces a + /// result + /// A sequence produced by projecting each element of the sequence with its lead pairing + /// + /// + /// or is . + /// + /// + /// is below 1. + /// /// - /// This operator evaluates in a deferred and streaming manner.
- ///
- /// The type of the elements in the source sequence - /// The type of the elements in the result sequence - /// The sequence over which to evaluate Lead - /// The offset (expressed as a positive number) by which to lead each element of the sequence - /// A default value supplied for the leading element when none is available - /// A projection function which accepts the current and subsequent (lead) element (in that order) and produces a result - /// A sequence produced by projecting each element of the sequence with its lead pairing - /// is . - /// is . - /// is below 1. - /// - /// This operator evaluates in a deferred and streaming manner.
+ /// + /// For elements of the sequence that are less than items from the end, is used as the lead value.
+ ///
+ /// + /// This operator evaluates in a deferred and streaming manner. + /// ///
public static IEnumerable Lead(this IEnumerable source, int offset, TSource defaultLeadValue, Func resultSelector) { From a8d4aa33791256e6f07ac8290af088ded4ce65eb Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 28 Oct 2023 12:37:28 -0500 Subject: [PATCH 056/124] Update documentation for `MaxItems` --- .../SuperLinq.SuperEnumerable.MaxItems.md | 41 ++++ .../apidoc/SuperLinq/MaxItems/MaxItems1.linq | 22 +++ .../apidoc/SuperLinq/MaxItems/MaxItems2.linq | 22 +++ .../apidoc/SuperLinq/MaxItems/MaxItems3.linq | 30 +++ .../apidoc/SuperLinq/MaxItems/MaxItems4.linq | 30 +++ .../apidoc/SuperLinq/MaxItems/MaxItems5.linq | 30 +++ .../apidoc/SuperLinq/MaxItems/MaxItems6.linq | 30 +++ Source/SuperLinq/MaxItems.cs | 178 ++++++++++++------ 8 files changed, 326 insertions(+), 57 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.MaxItems.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems5.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems6.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.MaxItems.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.MaxItems.md new file mode 100644 index 00000000..f5148402 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.MaxItems.md @@ -0,0 +1,41 @@ +--- +uid: SuperLinq.SuperEnumerable.MaxItems``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to get the maximum items from a sequence using `MaxItems`. +[!code-csharp[](SuperLinq/MaxItems/MaxItems1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.MaxItems``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to get the maximum items from a sequence using `MaxItems`. +[!code-csharp[](SuperLinq/MaxItems/MaxItems2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.MaxItemsBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get the maximum items from a sequence using `MaxItemsBy`. +[!code-csharp[](SuperLinq/MaxItems/MaxItems3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.MaxItemsBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to get the maximum items from a sequence using `MaxItemsBy`. +[!code-csharp[](SuperLinq/MaxItems/MaxItems4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.MaxByWithTies``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get the maximum items from a sequence using `MaxByWithTies`. +[!code-csharp[](SuperLinq/MaxItems/MaxItems5.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.MaxByWithTies``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to get the maximum items from a sequence using `MaxByWithTies`. +[!code-csharp[](SuperLinq/MaxItems/MaxItems6.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems1.linq new file mode 100644 index 00000000..ec540a03 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems1.linq @@ -0,0 +1,22 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + "A", "B", "C", "D", "F", + "a", "b", "c", "d", "f", +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MaxItems(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [F] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems2.linq new file mode 100644 index 00000000..81ba8026 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems2.linq @@ -0,0 +1,22 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + "A", "B", "C", "D", "F", + "a", "b", "c", "d", "f", +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MaxItems(StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [F] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems3.linq new file mode 100644 index 00000000..da64b023 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems3.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (cnt: 1, item: "A"), + (cnt: 2, item: "B"), + (cnt: 3, item: "C"), + (cnt: 4, item: "D"), + (cnt: 5, item: "E"), + (cnt: 1, item: "a"), + (cnt: 2, item: "b"), + (cnt: 3, item: "c"), + (cnt: 4, item: "d"), + (cnt: 5, item: "e"), +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MaxItemsBy(x => x.cnt); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, E), (5, e)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems4.linq new file mode 100644 index 00000000..bc9b2d7d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems4.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (cnt: 1, item: "A"), + (cnt: 2, item: "B"), + (cnt: 3, item: "C"), + (cnt: 4, item: "D"), + (cnt: 5, item: "E"), + (cnt: 1, item: "a"), + (cnt: 2, item: "b"), + (cnt: 3, item: "c"), + (cnt: 4, item: "d"), + (cnt: 5, item: "e"), +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MaxItemsBy(x => x.item, StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, E), (5, e)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems5.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems5.linq new file mode 100644 index 00000000..0d7305b3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems5.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (cnt: 1, item: "A"), + (cnt: 2, item: "B"), + (cnt: 3, item: "C"), + (cnt: 4, item: "D"), + (cnt: 5, item: "E"), + (cnt: 1, item: "a"), + (cnt: 2, item: "b"), + (cnt: 3, item: "c"), + (cnt: 4, item: "d"), + (cnt: 5, item: "e"), +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MaxByWithTies(x => x.cnt); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, E), (5, e)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems6.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems6.linq new file mode 100644 index 00000000..16246ecd --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MaxItems/MaxItems6.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (cnt: 1, item: "A"), + (cnt: 2, item: "B"), + (cnt: 3, item: "C"), + (cnt: 4, item: "D"), + (cnt: 5, item: "E"), + (cnt: 1, item: "a"), + (cnt: 2, item: "b"), + (cnt: 3, item: "c"), + (cnt: 4, item: "d"), + (cnt: 5, item: "e"), +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MaxByWithTies(x => x.item, StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, E), (5, e)] diff --git a/Source/SuperLinq/MaxItems.cs b/Source/SuperLinq/MaxItems.cs index 8bc17966..ecfd4984 100644 --- a/Source/SuperLinq/MaxItems.cs +++ b/Source/SuperLinq/MaxItems.cs @@ -3,18 +3,25 @@ public static partial class SuperEnumerable { /// - /// Returns all of the items that share the maximum value of a sequence. + /// Returns all of the items that share the maximum value of a sequence. /// - /// Type of elements in the sequence. - /// The source sequence. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// is . + /// /// /// - /// This operator is a shortcut for with a - /// direction of and a count of 1. + /// This operator is a shortcut for + /// with a direction of and a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MaxItems(this IEnumerable source) @@ -23,19 +30,28 @@ public static IEnumerable MaxItems(this IEnumerable source) } /// - /// Returns all of the items that share the maximum value of a sequence. + /// Returns all of the items that share the maximum value of a sequence. /// - /// Type of elements in the sequence. - /// The source sequence. - /// A to compare elements. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// A to compare elements. + /// + /// + /// is . + /// /// /// - /// This operator is a shortcut for with a - /// count of 1. + /// This operator is a shortcut for with a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MaxItems(this IEnumerable source, IComparer? comparer) @@ -44,21 +60,32 @@ public static IEnumerable MaxItems(this IEnumerable source, IComparer - /// Returns all of the items that share the maximum value of a sequence. + /// Returns all of the items that share the maximum value of a sequence. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// is . + /// /// /// - /// This operator is a shortcut for with a direction of - /// and a count of 1. + /// This operator is a shortcut for with a direction of and a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MaxItemsBy(this IEnumerable source, Func keySelector) @@ -67,21 +94,32 @@ public static IEnumerable MaxItemsBy(this IEnumerable - /// Returns all of the items that share the maximum value of a sequence. + /// Returns all of the items that share the maximum value of a sequence. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// is . + /// /// /// - /// This operator is a shortcut for with a direction of - /// and a count of 1. + /// This operator is a shortcut for with a direction of and a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MaxByWithTies(this IEnumerable source, Func keySelector) @@ -90,22 +128,35 @@ public static IEnumerable MaxByWithTies(this IEnumerable } /// - /// Returns all of the items that share the maximum value of a sequence. + /// Returns all of the items that share the maximum value of a sequence. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// A to compare keys. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// A to compare keys. + /// + /// + /// is . + /// /// /// - /// This operator is a shortcut for with a direction of and a count of 1. + /// This operator is a shortcut for with a direction of and a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MaxItemsBy(this IEnumerable source, Func keySelector, IComparer? comparer) @@ -114,22 +165,35 @@ public static IEnumerable MaxItemsBy(this IEnumerable - /// Returns all of the items that share the maximum value of a sequence. + /// Returns all of the items that share the maximum value of a sequence. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// A to compare keys. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// A to compare keys. + /// + /// + /// is . + /// /// /// - /// This operator is a shortcut for with a direction of and a count of 1. + /// This operator is a shortcut for with a direction of and a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MaxByWithTies(this IEnumerable source, Func keySelector, IComparer? comparer) From db9f9411f08b483e9fecf6d2efc985329dbf28aa Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 28 Oct 2023 16:50:13 -0500 Subject: [PATCH 057/124] Update documentation for `Memoize` --- .../SuperLinq.SuperEnumerable.Memoize.md | 6 +++ .../apidoc/SuperLinq/Memoize/Memoize.linq | 30 +++++++++++++ Source/SuperLinq/Memoize.cs | 42 ++++++++++--------- 3 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Memoize.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Memoize/Memoize.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Memoize.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Memoize.md new file mode 100644 index 00000000..4e53f451 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Memoize.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Memoize``1(System.Collections.Generic.IEnumerable{``0},System.Boolean) +example: [*content] +--- +The following code example demonstrates how to cache a sequence for repeated use using `Memoize`. +[!code-csharp[](SuperLinq/Memoize/Memoize.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Memoize/Memoize.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Memoize/Memoize.linq new file mode 100644 index 00000000..8e22fae4 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Memoize/Memoize.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var count = 0; +var sequence = Enumerable.Range(1, 10) + .Do(_ => count++); + +// get leading elements +var result = sequence.Memoize(); + +Console.WriteLine($"iterations: {count}"); +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); +Console.WriteLine($"iterations: {count}"); +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); +Console.WriteLine($"iterations: {count}"); + +// This code produces the following output: +// iterations: 0 +// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +// iterations: 10 +// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +// iterations: 10 diff --git a/Source/SuperLinq/Memoize.cs b/Source/SuperLinq/Memoize.cs index 4a1aa301..70993989 100644 --- a/Source/SuperLinq/Memoize.cs +++ b/Source/SuperLinq/Memoize.cs @@ -7,37 +7,41 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Creates a sequence that lazily caches the source as it is iterated for the first time, reusing the cache - /// thereafter for future re-iterations. By default, all sequences are cached, whether they are instantiated or - /// lazy. + /// Creates a sequence that lazily caches the source as it is iterated for the first time, reusing the cache + /// thereafter for future re-iterations. By default, all sequences are cached, whether they are instantiated or + /// lazy. /// /// - /// Type of elements in . - /// The source sequence. - /// Force caching of s. + /// Type of elements in . + /// + /// + /// The source sequence. + /// + /// + /// Force caching of s. + /// /// - /// Returns a sequence that corresponds to a cached version of the input sequence. + /// Returns a sequence that corresponds to a cached version of the input sequence. /// /// - /// is . + /// is . /// /// /// - /// The returned will cache items from in a thread-safe - /// manner. The sequence supplied in is not expected to be thread-safe but it is required - /// to be thread-agnostic. The iterator returned by is not thread-safe, - /// and access should be limited to a single thread/task or controlled via external locks. + /// The returned will cache items from in a thread-safe + /// manner. The sequence supplied in is not expected to be thread-safe but it is + /// required to be thread-agnostic. The iterator returned by is not + /// thread-safe, and access should be limited to a single thread/task or controlled via external locks. /// /// - /// By default, will choose the safe option and cache all s. will use an optimized form using , while other s will cache iteratively as - /// each element is requested. + /// By default, will choose the safe option and cache all s. + /// will use an optimized form using , + /// while other s will cache iteratively as each element is requested. /// /// - /// However, if is set to , then data in an will be returned directly and not cached. In most cases, this is safe, but if the - /// collection is modified in between uses, then different data may be returned for each iteration. + /// However, if is set to , then data in an will be returned directly and not cached. In most cases, this is safe, but if the + /// collection is modified in between uses, then different data may be returned for each iteration. /// /// public static IBuffer Memoize(this IEnumerable source, bool forceCache = true) From 5a1624abcc7e5b06352659e3df4f4a9e8d84c8e0 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 28 Oct 2023 17:38:04 -0500 Subject: [PATCH 058/124] Update documentation for `MinItems` --- .../SuperLinq.SuperEnumerable.MinItems.md | 41 ++++ .../apidoc/SuperLinq/MinItems/MinItems1.linq | 22 +++ .../apidoc/SuperLinq/MinItems/MinItems2.linq | 22 +++ .../apidoc/SuperLinq/MinItems/MinItems3.linq | 30 +++ .../apidoc/SuperLinq/MinItems/MinItems4.linq | 30 +++ .../apidoc/SuperLinq/MinItems/MinItems5.linq | 30 +++ .../apidoc/SuperLinq/MinItems/MinItems6.linq | 30 +++ Source/SuperLinq/MinItems.cs | 180 ++++++++++++------ 8 files changed, 327 insertions(+), 58 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.MinItems.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems5.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems6.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.MinItems.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.MinItems.md new file mode 100644 index 00000000..61819136 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.MinItems.md @@ -0,0 +1,41 @@ +--- +uid: SuperLinq.SuperEnumerable.MinItems``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to get the minimum items from a sequence using `MinItems`. +[!code-csharp[](SuperLinq/MinItems/MinItems1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.MinItems``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to get the minimum items from a sequence using `MinItems`. +[!code-csharp[](SuperLinq/MinItems/MinItems2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.MinItemsBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get the minimum items from a sequence using `MinItemsBy`. +[!code-csharp[](SuperLinq/MinItems/MinItems3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.MinItemsBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to get the minimum items from a sequence using `MinItemsBy`. +[!code-csharp[](SuperLinq/MinItems/MinItems4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.MinByWithTies``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get the minimum items from a sequence using `MinByWithTies`. +[!code-csharp[](SuperLinq/MinItems/MinItems5.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.MinByWithTies``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to get the minimum items from a sequence using `MinByWithTies`. +[!code-csharp[](SuperLinq/MinItems/MinItems6.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems1.linq new file mode 100644 index 00000000..7187d9f8 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems1.linq @@ -0,0 +1,22 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + "A", "B", "C", "D", "F", + "a", "b", "c", "d", "f", +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MinItems(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [a] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems2.linq new file mode 100644 index 00000000..cc60fae0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems2.linq @@ -0,0 +1,22 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + "A", "B", "C", "D", "F", + "a", "b", "c", "d", "f", +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MinItems(StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [A, a] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems3.linq new file mode 100644 index 00000000..d6ed8bd6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems3.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (cnt: 1, item: "A"), + (cnt: 2, item: "B"), + (cnt: 3, item: "C"), + (cnt: 4, item: "D"), + (cnt: 5, item: "E"), + (cnt: 1, item: "a"), + (cnt: 2, item: "b"), + (cnt: 3, item: "c"), + (cnt: 4, item: "d"), + (cnt: 5, item: "e"), +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MinItemsBy(x => x.cnt); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, A), (1, a)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems4.linq new file mode 100644 index 00000000..3eb77a80 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems4.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (cnt: 1, item: "A"), + (cnt: 2, item: "B"), + (cnt: 3, item: "C"), + (cnt: 4, item: "D"), + (cnt: 5, item: "E"), + (cnt: 1, item: "a"), + (cnt: 2, item: "b"), + (cnt: 3, item: "c"), + (cnt: 4, item: "d"), + (cnt: 5, item: "e"), +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MinItemsBy(x => x.item, StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, A), (1, a)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems5.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems5.linq new file mode 100644 index 00000000..61ca4538 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems5.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (cnt: 1, item: "A"), + (cnt: 2, item: "B"), + (cnt: 3, item: "C"), + (cnt: 4, item: "D"), + (cnt: 5, item: "E"), + (cnt: 1, item: "a"), + (cnt: 2, item: "b"), + (cnt: 3, item: "c"), + (cnt: 4, item: "d"), + (cnt: 5, item: "e"), +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MinByWithTies(x => x.cnt); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, A), (1, a)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems6.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems6.linq new file mode 100644 index 00000000..0f0130df --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/MinItems/MinItems6.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (cnt: 1, item: "A"), + (cnt: 2, item: "B"), + (cnt: 3, item: "C"), + (cnt: 4, item: "D"), + (cnt: 5, item: "E"), + (cnt: 1, item: "a"), + (cnt: 2, item: "b"), + (cnt: 3, item: "c"), + (cnt: 4, item: "d"), + (cnt: 5, item: "e"), +}.AsEnumerable(); + +// Find the maximum items of the sequence +var result = sequence + .MinByWithTies(x => x.item, StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, A), (1, a)] diff --git a/Source/SuperLinq/MinItems.cs b/Source/SuperLinq/MinItems.cs index 74b0b4bf..6ce62a26 100644 --- a/Source/SuperLinq/MinItems.cs +++ b/Source/SuperLinq/MinItems.cs @@ -3,18 +3,25 @@ public static partial class SuperEnumerable { /// - /// Returns all of the items that share the minimum value of a sequence. + /// Returns all of the items that share the minimum value of a sequence. /// - /// Type of elements in the sequence. - /// The source sequence. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// is . + /// /// /// - /// This operator is a shortcut for with a - /// direction of and a count of 1. + /// This operator is a shortcut for + /// with a direction of and a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MinItems(this IEnumerable source) @@ -23,19 +30,28 @@ public static IEnumerable MinItems(this IEnumerable source) } /// - /// Returns all of the items that share the minimum value of a sequence. + /// Returns all of the items that share the minimum value of a sequence. /// - /// Type of elements in the sequence. - /// The source sequence. - /// A to compare elements. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// A to compare elements. + /// + /// + /// is . + /// /// /// - /// This operator is a shortcut for with a - /// count of 1. + /// This operator is a shortcut for with a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MinItems(this IEnumerable source, IComparer? comparer) @@ -44,21 +60,32 @@ public static IEnumerable MinItems(this IEnumerable source, IComparer - /// Returns all of the items that share the minimum value of a sequence. + /// Returns all of the items that share the minimum value of a sequence. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// is . + /// /// /// - /// This operator is a shortcut for with a direction of - /// and a count of 1. + /// This operator is a shortcut for with a direction of and a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MinItemsBy(this IEnumerable source, Func keySelector) @@ -67,21 +94,32 @@ public static IEnumerable MinItemsBy(this IEnumerable - /// Returns all of the items that share the minimum value of a sequence. + /// Returns all of the items that share the minimum value of a sequence. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// is . + /// /// /// - /// This operator is a shortcut for with a direction of - /// and a count of 1. + /// This operator is a shortcut for with a direction of and a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MinByWithTies(this IEnumerable source, Func keySelector) @@ -90,22 +128,35 @@ public static IEnumerable MinByWithTies(this IEnumerable } /// - /// Returns all of the items that share the minimum value of a sequence. + /// Returns all of the items that share the minimum value of a sequence. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// A to compare keys. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// A to compare keys. + /// + /// + /// is . + /// /// /// - /// This operator is a shortcut for with a direction of and a count of 1. + /// This operator is a shortcut for with a direction of and a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MinItemsBy(this IEnumerable source, Func keySelector, IComparer? comparer) @@ -114,22 +165,35 @@ public static IEnumerable MinItemsBy(this IEnumerable - /// Returns all of the items that share the minimum value of a sequence. + /// Returns all of the items that share the minimum value of a sequence. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// A to compare keys. - /// is . + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// A to compare keys. + /// + /// + /// is . + /// /// - /// - /// This operator is a shortcut for with a direction of and a count of 1. + /// + /// This operator is a shortcut for with a direction of and a count of 1. /// /// - /// This operator uses deferred execution and streams it results. + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. /// /// public static IEnumerable MinByWithTies(this IEnumerable source, Func keySelector, IComparer? comparer) From e787c4bcf0b08bfe6e30ca9269400234233c3fea Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 30 Oct 2023 14:37:14 -0500 Subject: [PATCH 059/124] Update documentation for `Move` --- .../apidoc/SuperLinq.SuperEnumerable.Move.md | 6 +++ .../apidoc/SuperLinq/Move/Move.linq | 18 +++++++++ Source/SuperLinq/Move.cs | 39 +++++++++++-------- 3 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Move.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Move/Move.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Move.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Move.md new file mode 100644 index 00000000..f934adff --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Move.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Move``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Int32,System.Int32) +example: [*content] +--- +The following code example demonstrates how to move a subsequence from one location to another using `Move`. +[!code-csharp[](SuperLinq/Move/Move.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Move/Move.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Move/Move.linq new file mode 100644 index 00000000..9a16c8d3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Move/Move.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 6); + +// move a subsequence within the larger sequence +var result = sequence + .Move(3, 2, 0); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [3, 4, 0, 1, 2, 5] diff --git a/Source/SuperLinq/Move.cs b/Source/SuperLinq/Move.cs index 8a75b9ad..5cc5b916 100644 --- a/Source/SuperLinq/Move.cs +++ b/Source/SuperLinq/Move.cs @@ -3,30 +3,35 @@ public static partial class SuperEnumerable { /// - /// Returns a sequence with a range of elements in the source sequence - /// moved to a new offset. + /// Returns a sequence with a range of elements in the source sequence moved to a new offset. /// - /// Type of the source sequence. - /// The source sequence. + /// + /// Type of the source sequence. + /// + /// + /// The source sequence. + /// /// - /// The zero-based index identifying the first element in the range of - /// elements to move. - /// The count of items to move. + /// The zero-based index identifying the first element in the range of elements to move. + /// + /// + /// The count of items to move. + /// /// - /// The index where the specified range will be moved. + /// The index where the specified range will be moved. + /// + /// + /// is . + /// + /// + /// , , or is less than 0. + /// /// - /// A sequence with the specified range moved to the new position. + /// A sequence with the specified range moved to the new position. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// - /// - /// - /// The result variable will contain { 3, 4, 0, 1, 2, 5 }. - /// - public static IEnumerable Move(this IEnumerable source, int fromIndex, int count, int toIndex) { Guard.IsNotNull(source); From 41f50c1364cb24a2599f7c8dde5119a912b284f8 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 31 Oct 2023 15:05:13 -0500 Subject: [PATCH 060/124] Update documentation for `OnErrorResumeNext` --- ...rLinq.SuperEnumerable.OnErrorResumeNext.md | 20 +++++ .../OnErrorResumeNext/OnErrorResumeNext1.linq | 21 +++++ .../OnErrorResumeNext/OnErrorResumeNext2.linq | 22 +++++ .../OnErrorResumeNext/OnErrorResumeNext3.linq | 20 +++++ Source/SuperLinq/OnErrorResumeNext.cs | 90 +++++++++++++++---- 5 files changed, 154 insertions(+), 19 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.OnErrorResumeNext.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.OnErrorResumeNext.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.OnErrorResumeNext.md new file mode 100644 index 00000000..ad1a89ee --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.OnErrorResumeNext.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.OnErrorResumeNext``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to concatenate multiple sequences, regardless of any errors that may occur, using `OnErrorResumeNext`. +[!code-csharp[](SuperLinq/OnErrorResumeNext/OnErrorResumeNext1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.OnErrorResumeNext``1(System.Collections.Generic.IEnumerable{``0}[]) +example: [*content] +--- +The following code example demonstrates how to concatenate multiple sequences, regardless of any errors that may occur, using `OnErrorResumeNext`. +[!code-csharp[](SuperLinq/OnErrorResumeNext/OnErrorResumeNext2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.OnErrorResumeNext``1(System.Collections.Generic.IEnumerable{System.Collections.Generic.IEnumerable{``0}}) +example: [*content] +--- +The following code example demonstrates how to concatenate multiple sequences, regardless of any errors that may occur, using `OnErrorResumeNext`. +[!code-csharp[](SuperLinq/OnErrorResumeNext/OnErrorResumeNext3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext1.linq new file mode 100644 index 00000000..e1459f57 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext1.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +// this sequence will throw an exception on the 6th element +var sequence = Enumerable.Range(1, 5) + .Concat(SuperEnumerable.Throw(new InvalidOperationException())); + +// Skip over the error and enumerate the second sequence +var result = sequence + .OnErrorResumeNext( + Enumerable.Range(1, 5)); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext2.linq new file mode 100644 index 00000000..f72e14f4 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext2.linq @@ -0,0 +1,22 @@ + + SuperLinq + SuperLinq + + +// this sequence will throw an exception on the 6th element +var sequence = Enumerable.Range(1, 5) + .Concat(SuperEnumerable.Throw(new InvalidOperationException())); + +// Skip over the error and enumerate the second sequence +var result = SuperEnumerable + .OnErrorResumeNext( + sequence, + Enumerable.Range(1, 5)); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext3.linq new file mode 100644 index 00000000..dd527218 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/OnErrorResumeNext/OnErrorResumeNext3.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +// this sequence will throw an exception on the 6th element +var sequence = Enumerable.Range(1, 5) + .Concat(SuperEnumerable.Throw(new InvalidOperationException())); + +// Skip over the error and enumerate the second sequence +var result = new[] { sequence, Enumerable.Range(1, 5), } + .OnErrorResumeNext(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] diff --git a/Source/SuperLinq/OnErrorResumeNext.cs b/Source/SuperLinq/OnErrorResumeNext.cs index 0e0bc780..0fc59e75 100644 --- a/Source/SuperLinq/OnErrorResumeNext.cs +++ b/Source/SuperLinq/OnErrorResumeNext.cs @@ -3,14 +3,32 @@ public static partial class SuperEnumerable { /// - /// Creates a sequence that concatenates both given sequences, regardless of whether an error occurs. + /// Creates a sequence that concatenates both given sequences, regardless of whether an error occurs. /// - /// Source sequence element type. - /// First sequence. - /// Second sequence. - /// Sequence concatenating the elements of both sequences, ignoring errors. - /// or is . + /// + /// Source sequence element type. + /// + /// + /// First sequence. + /// + /// + /// Second sequence. + /// + /// + /// or is . + /// + /// + /// Sequence concatenating the elements of both sequences, ignoring errors. + /// + /// + /// + /// is enumerated until either the sequence completes or an error occurs during + /// enumeration. After either of these events, is then enumerated in the same way. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + /// public static IEnumerable OnErrorResumeNext(this IEnumerable first, IEnumerable second) { Guard.IsNotNull(first); @@ -20,13 +38,30 @@ public static IEnumerable OnErrorResumeNext(this IEnumerable - /// Creates a sequence that concatenates the given sequences, regardless of whether an error occurs in any of the - /// sequences. + /// Creates a sequence that concatenates the given sequences, regardless of whether an error occurs in any of + /// the sequences. /// - /// Source sequence element type. - /// Source sequences. - /// Sequence concatenating the elements of the given sequences, ignoring errors. - /// is . + /// + /// Source sequence element type. + /// + /// + /// Source sequences. + /// + /// + /// is . + /// + /// + /// Sequence concatenating the elements of the given sequences, ignoring errors. + /// + /// + /// + /// Each sequence of is enumerated until either the sequence completes or an error occurs during + /// enumeration. The returned sequence completes when all sub-sequences have been enumerated in this manner. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + /// public static IEnumerable OnErrorResumeNext(params IEnumerable[] sources) { Guard.IsNotNull(sources); @@ -35,13 +70,30 @@ public static IEnumerable OnErrorResumeNext(params IEnumerable } /// - /// Creates a sequence that concatenates the given sequences, regardless of whether an error occurs in any of the - /// sequences. + /// Creates a sequence that concatenates the given sequences, regardless of whether an error occurs in any of + /// the sequences. /// - /// Source sequence element type. - /// Source sequences. - /// Sequence concatenating the elements of the given sequences, ignoring errors. - /// is . + /// + /// Source sequence element type. + /// + /// + /// Source sequences. + /// + /// + /// is . + /// + /// + /// Sequence concatenating the elements of the given sequences, ignoring errors. + /// + /// + /// + /// Each sequence of is enumerated until either the sequence completes or an error occurs during + /// enumeration. The returned sequence completes when all sub-sequences have been enumerated in this manner. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + /// public static IEnumerable OnErrorResumeNext(this IEnumerable> sources) { Guard.IsNotNull(sources); From 4cf3725f3c5e368a087c7f0ef3b0bbc7fcb259d3 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 31 Oct 2023 15:33:31 -0500 Subject: [PATCH 061/124] Update documentation for `OrderBy` and `ThenBy` --- .../SuperLinq.SuperEnumerable.OrderBy.md | 27 +++ .../apidoc/SuperLinq/OrderBy/OrderBy1.linq | 24 +++ .../apidoc/SuperLinq/OrderBy/OrderBy2.linq | 24 +++ Source/SuperLinq/OrderBy.cs | 160 +++++++++++++----- 4 files changed, 197 insertions(+), 38 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.OrderBy.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/OrderBy/OrderBy1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/OrderBy/OrderBy2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.OrderBy.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.OrderBy.md new file mode 100644 index 00000000..c8e323a9 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.OrderBy.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.OrderBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to sort a sequence using `OrderBy` and `ThenBy`. +[!code-csharp[](SuperLinq/OrderBy/OrderBy1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ThenBy``2(System.Linq.IOrderedEnumerable{``0},System.Func{``0,``1},SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to sort a sequence using `OrderBy` and `ThenBy`. +[!code-csharp[](SuperLinq/OrderBy/OrderBy1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.OrderBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IComparer{``1},SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to sort a sequence using `OrderBy` and `ThenBy`. +[!code-csharp[](SuperLinq/OrderBy/OrderBy2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ThenBy``2(System.Linq.IOrderedEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IComparer{``1},SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to sort a sequence using `OrderBy` and `ThenBy`. +[!code-csharp[](SuperLinq/OrderBy/OrderBy2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/OrderBy/OrderBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/OrderBy/OrderBy1.linq new file mode 100644 index 00000000..773194e5 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/OrderBy/OrderBy1.linq @@ -0,0 +1,24 @@ + + SuperLinq + SuperLinq + + +var fruits = new[] +{ + "grape", "passionfruit", "banana", "Mango", + "Orange", "raspberry", "apple", "blueberry", +}; + +// Sort the strings first by their length and then +// alphabetically by passing the identity selector function. +var result = fruits + .OrderBy(fruit => fruit.Length) + .ThenBy(fruit => fruit); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [apple, grape, Mango, banana, Orange, blueberry, raspberry, passionfruit] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/OrderBy/OrderBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/OrderBy/OrderBy2.linq new file mode 100644 index 00000000..b3a5cee7 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/OrderBy/OrderBy2.linq @@ -0,0 +1,24 @@ + + SuperLinq + SuperLinq + + +var fruits = new[] +{ + "grape", "passionfruit", "banana", "Mango", + "Orange", "raspberry", "apple", "blueberry", +}; + +// Sort the strings first by their length and then +// alphabetically by passing the identity selector function. +var result = fruits + .OrderBy(fruit => fruit.Length) + .ThenBy(fruit => fruit, StringComparer.Ordinal); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [Mango, apple, grape, Orange, banana, blueberry, raspberry, passionfruit] diff --git a/Source/SuperLinq/OrderBy.cs b/Source/SuperLinq/OrderBy.cs index 6cff7448..ab25eaad 100644 --- a/Source/SuperLinq/OrderBy.cs +++ b/Source/SuperLinq/OrderBy.cs @@ -3,72 +3,156 @@ public static partial class SuperEnumerable { /// - /// Sorts the elements of a sequence in a particular direction (ascending, descending) according to a key + /// Sorts the elements of a sequence in a particular direction (ascending, descending) according to a key /// - /// The type of the elements in the source sequence - /// The type of the key used to order elements - /// The sequence to order - /// A key selector function - /// A direction in which to order the elements (ascending, descending) - /// An ordered copy of the source sequence - + /// + /// The type of the elements in the source sequence + /// + /// + /// The type of the key used to order elements + /// + /// + /// The sequence to order + /// + /// + /// A key selector function + /// + /// + /// A direction in which to order the elements (ascending, descending) + /// + /// + /// or is . + /// + /// + /// An ordered copy of the source sequence + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, OrderByDirection direction) { return OrderBy(source, keySelector, null, direction); } /// - /// Sorts the elements of a sequence in a particular direction (ascending, descending) according to a key + /// Sorts the elements of a sequence in a particular direction (ascending, descending) according to a key /// - /// The type of the elements in the source sequence - /// The type of the key used to order elements - /// The sequence to order - /// A key selector function - /// A direction in which to order the elements (ascending, descending) - /// A comparer used to define the semantics of element comparison - /// An ordered copy of the source sequence - + /// + /// The type of the elements in the source sequence + /// + /// + /// The type of the key used to order elements + /// + /// + /// The sequence to order + /// + /// + /// A key selector function + /// + /// + /// An to compare keys + /// + /// + /// A direction in which to order the elements (ascending, descending) + /// + /// + /// or is . + /// + /// + /// An ordered copy of the source sequence + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, IComparer? comparer, OrderByDirection direction) { Guard.IsNotNull(source); Guard.IsNotNull(keySelector); return direction == OrderByDirection.Ascending - ? source.OrderBy(keySelector, comparer) - : source.OrderByDescending(keySelector, comparer); + ? source.OrderBy(keySelector, comparer) + : source.OrderByDescending(keySelector, comparer); } /// - /// Performs a subsequent ordering of elements in a sequence in a particular direction (ascending, descending) according to a key + /// Performs a subsequent ordering of elements of a sequence in a particular direction (ascending, descending) according to a key /// - /// The type of the elements in the source sequence - /// The type of the key used to order elements - /// The sequence to order - /// A key selector function - /// A direction in which to order the elements (ascending, descending) - /// An ordered copy of the source sequence - + /// + /// The type of the elements in the source sequence + /// + /// + /// The type of the key used to order elements + /// + /// + /// The sequence to order + /// + /// + /// A key selector function + /// + /// + /// A direction in which to order the elements (ascending, descending) + /// + /// + /// or is . + /// + /// + /// An ordered copy of the source sequence + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector, OrderByDirection direction) { return ThenBy(source, keySelector, null, direction); } /// - /// Performs a subsequent ordering of elements in a sequence in a particular direction (ascending, descending) according to a key + /// Performs a subsequent ordering of elements of a sequence in a particular direction (ascending, descending) according to a key /// - /// The type of the elements in the source sequence - /// The type of the key used to order elements - /// The sequence to order - /// A key selector function - /// A direction in which to order the elements (ascending, descending) - /// A comparer used to define the semantics of element comparison - /// An ordered copy of the source sequence - + /// + /// The type of the elements in the source sequence + /// + /// + /// The type of the key used to order elements + /// + /// + /// The sequence to order + /// + /// + /// A key selector function + /// + /// + /// An to compare keys + /// + /// + /// A direction in which to order the elements (ascending, descending) + /// + /// + /// or is . + /// + /// + /// An ordered copy of the source sequence + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector, IComparer? comparer, OrderByDirection direction) { Guard.IsNotNull(source); Guard.IsNotNull(keySelector); return direction == OrderByDirection.Ascending - ? source.ThenBy(keySelector, comparer) - : source.ThenByDescending(keySelector, comparer); + ? source.ThenBy(keySelector, comparer) + : source.ThenByDescending(keySelector, comparer); } } From fae114ca877b2b1528686e037bbacf86c4bb9b8f Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 1 Nov 2023 08:03:27 -0500 Subject: [PATCH 062/124] Update documentation for `Pad` --- .../apidoc/SuperLinq.SuperEnumerable.Pad.md | 20 +++ .../apidoc/SuperLinq/Pad/Pad1.linq | 18 +++ .../apidoc/SuperLinq/Pad/Pad2.linq | 18 +++ .../apidoc/SuperLinq/Pad/Pad3.linq | 18 +++ Source/SuperLinq/Pad.cs | 121 +++++++++--------- 5 files changed, 138 insertions(+), 57 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Pad.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Pad.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Pad.md new file mode 100644 index 00000000..d77ec7df --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Pad.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.Pad``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to pad a sequence using `Pad`. +[!code-csharp[](SuperLinq/Pad/Pad1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Pad``1(System.Collections.Generic.IEnumerable{``0},System.Int32,``0) +example: [*content] +--- +The following code example demonstrates how to pad a sequence using `Pad`. +[!code-csharp[](SuperLinq/Pad/Pad2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Pad``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{System.Int32,``0}) +example: [*content] +--- +The following code example demonstrates how to pad a sequence using `Pad`. +[!code-csharp[](SuperLinq/Pad/Pad3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad1.linq new file mode 100644 index 00000000..2105f791 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 3); + +// Pad a sequence until it is at least a certain length +var result = sequence + .Pad(6); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 0, 0, 0] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad2.linq new file mode 100644 index 00000000..662f3a60 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad2.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 3); + +// Pad a sequence until it is at least a certain length +var result = sequence + .Pad(6, -5); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, -5, -5, -5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad3.linq new file mode 100644 index 00000000..2b6fde1f --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Pad/Pad3.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 3); + +// Pad a sequence until it is at least a certain length +var result = sequence + .Pad(6, i => -i); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, -3, -4, -5] diff --git a/Source/SuperLinq/Pad.cs b/Source/SuperLinq/Pad.cs index 9ebda788..f206551b 100644 --- a/Source/SuperLinq/Pad.cs +++ b/Source/SuperLinq/Pad.cs @@ -3,90 +3,97 @@ public static partial class SuperEnumerable { /// - /// Pads a sequence with default values if it is narrower (shorter - /// in length) than a given width. + /// Pads a sequence with default values if it is narrower (shorter in length) than a given width. /// - /// The type of the elements of . - /// The sequence to pad. - /// The width/length below which to pad. + /// + /// The type of the elements of . + /// + /// + /// The sequence to pad. + /// + /// + /// The width/length below which to pad. + /// + /// + /// is . + /// + /// + /// is less than 0. + /// /// - /// Returns a sequence that is at least as wide/long as the width/length - /// specified by the parameter. + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// - /// - /// - /// The result variable, when iterated over, will yield - /// 123, 456, 789 and two zeroes, in turn. - /// - /// is . - /// is less than 0. public static IEnumerable Pad(this IEnumerable source, int width) { return Pad(source, width, padding: default); } + /// - /// Pads a sequence with a given filler value if it is narrower (shorter - /// in length) than a given width. + /// Pads a sequence with default values if it is narrower (shorter in length) than a given width. /// - /// The type of the elements of . - /// The sequence to pad. - /// The width/length below which to pad. - /// The value to use for padding. + /// + /// The type of the elements of . + /// + /// + /// The sequence to pad. + /// + /// + /// The width/length below which to pad. + /// + /// + /// The value to use for padding. + /// + /// + /// is . + /// + /// + /// is less than 0. + /// /// - /// Returns a sequence that is at least as wide/long as the width/length - /// specified by the parameter. + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// - /// - /// - /// The result variable, when iterated over, will yield - /// 123, 456, and 789 followed by two occurrences of -1, in turn. - /// - /// is . - /// is less than 0. public static IEnumerable Pad(this IEnumerable source, int width, TSource padding) { return Pad(source, width, paddingSelector: _ => padding); } /// - /// Pads a sequence with a dynamic filler value if it is narrower (shorter - /// in length) than a given width. + /// Pads a sequence with default values if it is narrower (shorter in length) than a given width. /// - /// The type of the elements of . - /// The sequence to pad. - /// The width/length below which to pad. - /// Function to calculate padding. + /// + /// The type of the elements of . + /// + /// + /// The sequence to pad. + /// + /// + /// The width/length below which to pad. + /// + /// + /// A function to generate the value used as padding. + /// + /// + /// or is . + /// + /// + /// is less than 0. + /// /// - /// Returns a sequence that is at least as wide/long as the width/length - /// specified by the parameter. + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// - /// - /// -i); - /// ]]> - /// The result variable, when iterated over, will yield - /// 0, 1, 2, -3 and -4, in turn. - /// - /// is . - /// is . - /// is less than 0. public static IEnumerable Pad(this IEnumerable source, int width, Func paddingSelector) { Guard.IsNotNull(source); From 4dc415ed25042dcb28f99b2d4e259f70f7ba2f71 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 1 Nov 2023 08:29:36 -0500 Subject: [PATCH 063/124] Update documentation for `PadStart` --- .../SuperLinq.SuperEnumerable.PadStart.md | 20 +++ .../apidoc/SuperLinq/PadStart/PadStart1.linq | 18 +++ .../apidoc/SuperLinq/PadStart/PadStart2.linq | 18 +++ .../apidoc/SuperLinq/PadStart/PadStart3.linq | 18 +++ Source/SuperLinq/PadStart.cs | 120 ++++++++++-------- 5 files changed, 138 insertions(+), 56 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PadStart.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PadStart.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PadStart.md new file mode 100644 index 00000000..07486248 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PadStart.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.PadStart``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to pad a sequence using `PadStart`. +[!code-csharp[](SuperLinq/PadStart/PadStart1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.PadStart``1(System.Collections.Generic.IEnumerable{``0},System.Int32,``0) +example: [*content] +--- +The following code example demonstrates how to pad a sequence using `PadStart`. +[!code-csharp[](SuperLinq/PadStart/PadStart2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.PadStart``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{System.Int32,``0}) +example: [*content] +--- +The following code example demonstrates how to pad a sequence using `PadStart`. +[!code-csharp[](SuperLinq/PadStart/PadStart3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart1.linq new file mode 100644 index 00000000..9f663750 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 3); + +// Pad a sequence until it is at least a certain length +var result = sequence + .PadStart(6); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [0, 0, 0, 1, 2, 3] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart2.linq new file mode 100644 index 00000000..53466c18 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart2.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 3); + +// Pad a sequence until it is at least a certain length +var result = sequence + .PadStart(6, -5); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [-5, -5, -5, 1, 2, 3] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart3.linq new file mode 100644 index 00000000..20426f99 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PadStart/PadStart3.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 3); + +// Pad a sequence until it is at least a certain length +var result = sequence + .PadStart(6, i => -i); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [0, -1, -2, 1, 2, 3] diff --git a/Source/SuperLinq/PadStart.cs b/Source/SuperLinq/PadStart.cs index 40a64216..d1403bf1 100644 --- a/Source/SuperLinq/PadStart.cs +++ b/Source/SuperLinq/PadStart.cs @@ -3,91 +3,99 @@ public static partial class SuperEnumerable { /// - /// Pads a sequence with default values in the beginning if it is narrower (shorter - /// in length) than a given width. + /// Pads a sequence with default values in the beginning if it is narrower (shorter in length) than a given + /// width. /// - /// The type of the elements of . - /// The sequence to pad. - /// The width/length below which to pad. + /// + /// The type of the elements of . + /// + /// + /// The sequence to pad. + /// + /// + /// The width/length below which to pad. + /// + /// + /// is . + /// + /// + /// is less than 0. + /// /// - /// Returns a sequence that is at least as wide/long as the width/length - /// specified by the parameter. + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// - /// - /// - /// The result variable will contain { 0, 0, 123, 456, 789 }. - /// - /// is . - /// is less than 0. public static IEnumerable PadStart(this IEnumerable source, int width) { return PadStart(source, width, padding: default); } /// - /// Pads a sequence with a given filler value in the beginning if it is narrower (shorter - /// in length) than a given width. - /// An additional parameter specifies the value to use for padding. + /// Pads a sequence with default values in the beginning if it is narrower (shorter in length) than a given + /// width. /// - /// The type of the elements of . - /// The sequence to pad. - /// The width/length below which to pad. - /// The value to use for padding. + /// + /// The type of the elements of . + /// + /// + /// The sequence to pad. + /// + /// + /// The width/length below which to pad. + /// + /// + /// The value to use for padding. + /// + /// + /// is . + /// + /// + /// is less than 0. + /// /// - /// Returns a sequence that is at least as wide/long as the width/length - /// specified by the parameter. + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// - /// - /// - /// The result variable will contain { -1, -1, 123, 456, 789 }. - /// - /// is . - /// is less than 0. public static IEnumerable PadStart(this IEnumerable source, int width, TSource padding) { return PadStart(source, width, paddingSelector: _ => padding); } /// - /// Pads a sequence with a dynamic filler value in the beginning if it is narrower (shorter - /// in length) than a given width. - /// An additional parameter specifies the function to calculate padding. + /// Pads a sequence with default values in the beginning if it is narrower (shorter in length) than a given + /// width. /// - /// The type of the elements of . - /// The sequence to pad. - /// The width/length below which to pad. + /// + /// The type of the elements of . + /// + /// + /// The sequence to pad. + /// + /// + /// The width/length below which to pad. + /// /// - /// Function to calculate padding given the index of the missing element. + /// A function to generate the value used as padding. /// + /// + /// or is . + /// + /// + /// is less than 0. + /// /// - /// Returns a sequence that is at least as wide/long as the width/length - /// specified by the parameter. + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// - /// - /// -i); - /// ]]> - /// The result variable will contain { 0, -1, -2, 123, 456, 789 }. - /// - /// is . - /// is . - /// is less than 0. public static IEnumerable PadStart(this IEnumerable source, int width, Func paddingSelector) { Guard.IsNotNull(source); From f375a370a346ff6e8310b005c9e703282c7ccdda Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 1 Nov 2023 10:00:40 -0500 Subject: [PATCH 064/124] Update documentation for `PartialSort` --- .../SuperLinq.SuperEnumerable.PartialSort.md | 28 ++ ...SuperLinq.SuperEnumerable.PartialSortBy.md | 28 ++ .../SuperLinq/PartialSort/PartialSort1.linq | 47 +++ .../SuperLinq/PartialSort/PartialSort2.linq | 47 +++ .../SuperLinq/PartialSort/PartialSort3.linq | 32 ++ .../SuperLinq/PartialSort/PartialSort4.linq | 33 ++ .../PartialSortBy/PartialSortBy1.linq | 32 ++ .../PartialSortBy/PartialSortBy2.linq | 33 ++ .../PartialSortBy/PartialSortBy3.linq | 33 ++ .../PartialSortBy/PartialSortBy4.linq | 34 ++ Source/SuperLinq/PartialSort.cs | 354 ++++++++++++------ 11 files changed, 584 insertions(+), 117 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PartialSort.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PartialSortBy.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PartialSort.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PartialSort.md new file mode 100644 index 00000000..6365eb0a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PartialSort.md @@ -0,0 +1,28 @@ +--- +uid: SuperLinq.SuperEnumerable.PartialSort``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `PartialSort`. +[!code-csharp[](SuperLinq/PartialSort/PartialSort1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.PartialSort``1(System.Collections.Generic.IEnumerable{``0},System.Int32,SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `PartialSort`. +[!code-csharp[](SuperLinq/PartialSort/PartialSort2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.PartialSort``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Collections.Generic.IComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `PartialSort`. +[!code-csharp[](SuperLinq/PartialSort/PartialSort3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.PartialSort``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Collections.Generic.IComparer{``0},SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `PartialSort`. +[!code-csharp[](SuperLinq/PartialSort/PartialSort4.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PartialSortBy.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PartialSortBy.md new file mode 100644 index 00000000..05774d0b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PartialSortBy.md @@ -0,0 +1,28 @@ +--- +uid: SuperLinq.SuperEnumerable.PartialSortBy``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `PartialSort`. +[!code-csharp[](SuperLinq/PartialSortBy/PartialSortBy1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.PartialSortBy``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``1},SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `PartialSort`. +[!code-csharp[](SuperLinq/PartialSortBy/PartialSortBy2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.PartialSortBy``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``1},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `PartialSort`. +[!code-csharp[](SuperLinq/PartialSortBy/PartialSortBy3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.PartialSortBy``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``1},System.Collections.Generic.IComparer{``1},SuperLinq.OrderByDirection) +example: [*content] +--- +The following code example demonstrates how to get the top N items of a sequence using `PartialSort`. +[!code-csharp[](SuperLinq/PartialSortBy/PartialSortBy4.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort1.linq new file mode 100644 index 00000000..2c83188b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort1.linq @@ -0,0 +1,47 @@ + + SuperLinq + SuperLinq + + +var sequence = new Item[] +{ + new(key: 5, text: "1"), + new(key: 5, text: "2"), + new(key: 4, text: "3"), + new(key: 4, text: "4"), + new(key: 3, text: "5"), + new(key: 3, text: "6"), + new(key: 2, text: "7"), + new(key: 2, text: "8"), + new(key: 1, text: "9"), + new(key: 1, text: "10"), +}; + +// Get the top N items +var result = sequence.PartialSort(3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, 9), (1, 10), (2, 7)] + +class Item : IComparable +{ + public Item(int key, string text) + { + Key = key; + Text = text; + } + + public int Key { get; } + public string Text { get; } + + public int CompareTo(Item other) => + this.Key.CompareTo(other.Key); + + public override string ToString() => + $"({this.Key}, {this.Text})"; +} diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort2.linq new file mode 100644 index 00000000..f500f4d7 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort2.linq @@ -0,0 +1,47 @@ + + SuperLinq + SuperLinq + + +var sequence = new Item[] +{ + new(key: 5, text: "1"), + new(key: 5, text: "2"), + new(key: 4, text: "3"), + new(key: 4, text: "4"), + new(key: 3, text: "5"), + new(key: 3, text: "6"), + new(key: 2, text: "7"), + new(key: 2, text: "8"), + new(key: 1, text: "9"), + new(key: 1, text: "10"), +}; + +// Get the top N items +var result = sequence.PartialSort(3, OrderByDirection.Descending); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, 1), (5, 2), (4, 3)] + +class Item : IComparable +{ + public Item(int key, string text) + { + Key = key; + Text = text; + } + + public int Key { get; } + public string Text { get; } + + public int CompareTo(Item other) => + this.Key.CompareTo(other.Key); + + public override string ToString() => + $"({this.Key}, {this.Text})"; +} diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort3.linq new file mode 100644 index 00000000..0dbb10c7 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort3.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N items +var result = sequence + .PartialSort( + 3, + Comparer<(int key, string text)>.Create((x, y) => x.key.CompareTo(y.key))); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, 9), (1, 10), (2, 7)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort4.linq new file mode 100644 index 00000000..8ecf4dd6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSort/PartialSort4.linq @@ -0,0 +1,33 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N items +var result = sequence + .PartialSort( + 3, + Comparer<(int key, string text)>.Create((x, y) => x.key.CompareTo(y.key)), + OrderByDirection.Descending); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, 1), (5, 2), (4, 3)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy1.linq new file mode 100644 index 00000000..3b4092e8 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy1.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N items +var result = sequence + .PartialSortBy( + 3, + x => x.key); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, 9), (1, 10), (2, 7)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy2.linq new file mode 100644 index 00000000..c721fbb6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy2.linq @@ -0,0 +1,33 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N items +var result = sequence + .PartialSortBy( + 3, + x => x.key, + OrderByDirection.Descending); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, 1), (5, 2), (4, 3)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy3.linq new file mode 100644 index 00000000..713c77ce --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy3.linq @@ -0,0 +1,33 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N items +var result = sequence + .PartialSortBy( + 1, + x => x.key, + Comparer.Create((x, y) => (x % 2).CompareTo(y % 2))); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(4, 3)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy4.linq new file mode 100644 index 00000000..85636a70 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PartialSortBy/PartialSortBy4.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N items +var result = sequence + .PartialSortBy( + 1, + x => x.key, + Comparer.Create((x, y) => (x % 2).CompareTo(y % 2)), + OrderByDirection.Descending); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(5, 1), (5, 2), (3, 5), (3, 6), (1, 9), (1, 10)] diff --git a/Source/SuperLinq/PartialSort.cs b/Source/SuperLinq/PartialSort.cs index 9c79e46e..8100c8e6 100644 --- a/Source/SuperLinq/PartialSort.cs +++ b/Source/SuperLinq/PartialSort.cs @@ -3,23 +3,34 @@ public static partial class SuperEnumerable { /// - /// Executes a partial sort of the top elements of a sequence. If - /// is less than the total number of elements in , then this method will improve - /// performance. + /// Executes a partial sort of the top elements of a sequence. If is less than the total number of elements in , then this method will + /// improve performance. /// - /// Type of elements in the sequence. - /// The source sequence. - /// Number of (maximum) elements to return. - /// A sequence containing at most top elements from source, in their ascending - /// order. - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// A sequence containing at most top elements from source, in their ascending order. + /// + /// + /// is . + /// + /// + /// is less than 1. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This operation is an O(n * log(K)) where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This operator uses deferred execution and streams it results. /// /// public static IEnumerable PartialSort(this IEnumerable source, int count) @@ -28,24 +39,37 @@ public static IEnumerable PartialSort(this IEnumerable source, int coun } /// - /// Executes a partial sort of the top elements of a sequence. - /// If is less than the total number of elements in , then this - /// method will improve performance. + /// Executes a partial sort of the top elements of a + /// sequence. If is less than the total number of elements in , then this method will improve performance. /// - /// Type of elements in the sequence. - /// The source sequence. - /// Number of (maximum) elements to return. - /// The direction in which to sort the elements - /// A sequence containing at most top elements from source, in the specified - /// order. - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// The direction in which to sort the elements + /// + /// + /// A sequence containing at most top elements from source, in the specified order. + /// + /// + /// is . + /// + /// + /// is less than 1. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This operation is an O(n * log(K)) where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This operator uses deferred execution and streams it results. /// /// public static IEnumerable PartialSort( @@ -55,24 +79,37 @@ public static IEnumerable PartialSort( } /// - /// Executes a partial sort of the top elements of a sequence, using to compare elements. If is less than the total number of elements in - /// , then this method will improve performance. + /// Executes a partial sort of the top elements of a sequence, using to compare elements. If is less than the total number of elements + /// in , then this method will improve performance. /// - /// Type of elements in the sequence. - /// The source sequence. - /// Number of (maximum) elements to return. - /// A to compare elements. - /// A sequence containing at most top elements from source, in their ascending - /// order. - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// A to compare elements. + /// + /// + /// A sequence containing at most top elements from source, in their ascending order. + /// + /// + /// is . + /// + /// + /// is less than 1. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This operation is an O(n * log(K)) where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This operator uses deferred execution and streams it results. /// /// public static IEnumerable PartialSort( @@ -83,25 +120,40 @@ public static IEnumerable PartialSort( } /// - /// Executes a partial sort of the top elements of a sequence, - /// using to compare elements. If is less than the total number - /// of elements in , then this method will improve performance. + /// Executes a partial sort of the top elements of a + /// sequence, using to compare elements. If is less than + /// the total number of elements in , then this method will improve performance. /// - /// Type of elements in the sequence. - /// The source sequence. - /// Number of (maximum) elements to return. - /// A to compare elements. - /// The direction in which to sort the elements - /// A sequence containing at most top elements from source, in the specified - /// order. - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// The source sequence. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// A to compare elements. + /// + /// + /// The direction in which to sort the elements + /// + /// + /// A sequence containing at most top elements from source, in the specified order. + /// + /// + /// is . + /// + /// + /// is less than 1. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This operation is an O(n * log(K)) where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This operator uses deferred execution and streams it results. /// /// public static IEnumerable PartialSort( @@ -146,26 +198,41 @@ static IEnumerable Core(IEnumerable source, int count, IComparer compar } /// - /// Executes a partial sort of the top elements of a sequence according to the key for each - /// element. If is less than the total number of elements in , - /// then this method will improve performance. + /// Executes a partial sort of the top elements of a sequence according to the key for + /// each element. If is less than the total number of elements in , then this method will improve performance. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// Number of (maximum) elements to return. - /// A sequence containing at most top elements from source, in ascending order of - /// their keys. - /// is . - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// or is . + /// + /// + /// is less than 1. + /// + /// + /// A sequence containing at most top elements from source, in ascending order of their + /// keys. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This operation is an O(n * log(K)) where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This operator uses deferred execution and streams it results. /// /// public static IEnumerable PartialSortBy( @@ -176,27 +243,44 @@ public static IEnumerable PartialSortBy( } /// - /// Executes a partial sort of the top elements of a sequence - /// according to the key for each element. If is less than the total number of elements in - /// , then this method will improve performance. + /// Executes a partial sort of the top elements of a + /// sequence according to the key for each element. If is less than the total number of + /// elements in , then this method will improve performance. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// Number of (maximum) elements to return. - /// The direction in which to sort the elements - /// A sequence containing at most top elements from source, in the specified order - /// of their keys. - /// is . - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// The direction in which to sort the elements + /// + /// + /// or is . + /// + /// + /// is less than 1. + /// + /// + /// A sequence containing at most top elements from source, in the specified order of + /// their keys. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This operation is an O(n * log(K)) where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This operator uses deferred execution and streams it results. /// /// public static IEnumerable PartialSortBy( @@ -207,27 +291,44 @@ public static IEnumerable PartialSortBy( } /// - /// Executes a partial sort of the top elements of a sequence according to the key for each - /// element, using to compare the keys. If is less than the - /// total number of elements in , then this method will improve performance. + /// Executes a partial sort of the top elements of a sequence according to the key for + /// each element, using to compare the keys. If is less + /// than the total number of elements in , then this method will improve performance. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// Number of (maximum) elements to return. - /// A to compare elements. - /// A sequence containing at most top elements from source, in ascending order of - /// their keys. - /// is . - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// A to compare elements. + /// + /// + /// or is . + /// + /// + /// is less than 1. + /// + /// + /// A sequence containing at most top elements from source, in ascending order of their + /// keys. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This operation is an O(n * log(K)) where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This operator uses deferred execution and streams it results. /// /// public static IEnumerable PartialSortBy( @@ -239,29 +340,48 @@ public static IEnumerable PartialSortBy( } /// - /// Executes a partial sort of the top elements of a sequence - /// according to the key for each element, using to compare the keys. If is less than the total number of elements in , then this method will - /// improve performance. + /// Executes a partial sort of the top elements of a + /// sequence according to the key for each element, using to compare the keys. If + /// is less than the total number of elements in , then this + /// method will improve performance. /// - /// Type of elements in the sequence. - /// Type of keys. - /// The source sequence. - /// A function to extract a key from an element. - /// Number of (maximum) elements to return. - /// A to compare elements. - /// The direction in which to sort the elements - /// A sequence containing at most top elements from source, in the specified order - /// of their keys. - /// is . - /// is . - /// is less than 1. + /// + /// Type of elements in the sequence. + /// + /// + /// Type of keys. + /// + /// + /// The source sequence. + /// + /// + /// A function to extract a key from an element. + /// + /// + /// Number of (maximum) elements to return. + /// + /// + /// A to compare elements. + /// + /// + /// The direction in which to sort the elements + /// + /// + /// or is . + /// + /// + /// is less than 1. + /// + /// + /// A sequence containing at most top elements from source, in the specified order of + /// their keys. + /// /// /// - /// This operation is an O(n * log(K)) where K is . + /// This operation is an O(n * log(K)) where K is . /// /// - /// This operator uses deferred execution and streams it results. + /// This operator uses deferred execution and streams it results. /// /// public static IEnumerable PartialSortBy( From f06c81c75f8b0bb7f82033985113bfae97647f60 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 2 Nov 2023 11:48:02 -0500 Subject: [PATCH 065/124] Update documentation for `Partition` --- .../SuperLinq.SuperEnumerable.Partition.md | 13 +++ .../SuperLinq/Partition/Partition1.linq | 24 ++++++ .../SuperLinq/Partition/Partition2.linq | 24 ++++++ Source/SuperLinq/Partition.cs | 86 ++++++++++--------- 4 files changed, 108 insertions(+), 39 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Partition.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Partition/Partition1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Partition/Partition2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Partition.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Partition.md new file mode 100644 index 00000000..9545849c --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Partition.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.Partition``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to partition a sequence using `Partition`. +[!code-csharp[](SuperLinq/Partition/Partition1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Partition``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean},System.Func{System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to partition a sequence using `Partition`. +[!code-csharp[](SuperLinq/Partition/Partition2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Partition/Partition1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Partition/Partition1.linq new file mode 100644 index 00000000..f3cbc3a1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Partition/Partition1.linq @@ -0,0 +1,24 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 10); + +// Partition a sequence +var (evens, odds) = sequence + .Partition(x => x % 2 == 0); + +Console.WriteLine( + "evens: [" + + string.Join(", ", evens) + + "]"); + +Console.WriteLine( + "odds: [" + + string.Join(", ", odds) + + "]"); + +// This code produces the following output: +// evens: [0, 2, 4, 6, 8] +// odds: [1, 3, 5, 7, 9] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Partition/Partition2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Partition/Partition2.linq new file mode 100644 index 00000000..852edf5a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Partition/Partition2.linq @@ -0,0 +1,24 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 10); + +// Partition a sequence +var (evens, odds) = sequence + .Partition(x => x % 2 == 0, ValueTuple.Create); + +Console.WriteLine( + "evens: [" + + string.Join(", ", evens) + + "]"); + +Console.WriteLine( + "odds: [" + + string.Join(", ", odds) + + "]"); + +// This code produces the following output: +// evens: [0, 2, 4, 6, 8] +// odds: [1, 3, 5, 7, 9] diff --git a/Source/SuperLinq/Partition.cs b/Source/SuperLinq/Partition.cs index cbc2e19d..1d4e712e 100644 --- a/Source/SuperLinq/Partition.cs +++ b/Source/SuperLinq/Partition.cs @@ -3,25 +3,31 @@ public static partial class SuperEnumerable { /// - /// Partitions or splits a sequence in two using a predicate. + /// Partitions or splits a sequence in two using a predicate. /// - /// The source sequence. - /// The predicate function. - /// Type of source elements. + /// + /// The source sequence. + /// + /// + /// The predicate function. + /// + /// + /// Type of source elements. + /// + /// + /// is . + /// /// - /// A tuple of elements satisfying the predicate and those that do not, - /// respectively. + /// A tuple of elements satisfying the predicate and those that do not, respectively. /// - /// is null - /// - /// x % 2 == 0); - /// ]]> - /// The evens variable, when iterated over, will yield 0, 2, 4, 6 - /// and then 8. The odds variable, when iterated over, will yield - /// 1, 3, 5, 7 and then 9. - /// + /// + /// + /// + /// + /// + /// This method executes immediately. + /// + /// public static (IEnumerable True, IEnumerable False) Partition(this IEnumerable source, Func predicate) { @@ -29,34 +35,36 @@ public static (IEnumerable True, IEnumerable False) } /// - /// Partitions or splits a sequence in two using a predicate and then - /// projects a result from the two. + /// Partitions or splits a sequence in two using a predicate and then projects a result from the two. /// - /// The source sequence. - /// The predicate function. + /// + /// The source sequence. + /// + /// + /// The predicate function. + /// /// - /// Function that projects the result from sequences of elements that - /// satisfy the predicate and those that do not, respectively, passed as - /// arguments. + /// Function that projects the result from sequences of elements that satisfy the predicate and those that do + /// not, respectively, passed as arguments. /// - /// Type of source elements. - /// Type of the result. + /// + /// Type of source elements. + /// + /// + /// Type of the result. + /// + /// + /// , , or is . + /// /// - /// The return value from . + /// The return value from . /// - /// is null - /// is null - /// is null - /// - /// x % 2 == 0, ValueTuple.Create); - /// ]]> - /// The evens variable, when iterated over, will yield 0, 2, 4, 6 - /// and then 8. The odds variable, when iterated over, will yield - /// 1, 3, 5, 7 and then 9. - /// + /// + /// + /// This method executes immediately. + /// + /// public static TResult Partition( this IEnumerable source, Func predicate, From b5a085f5c12ce15cf0a5b4247206d26e52a2e6cd Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 2 Nov 2023 12:16:17 -0500 Subject: [PATCH 066/124] Update documentation for `Permutations` --- .../SuperLinq.SuperEnumerable.Permutations.md | 6 +++ .../SuperLinq/Permutations/Permutations.linq | 44 +++++++++++++++++++ Source/SuperLinq/Permutations.cs | 43 +++++++++++++----- 3 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Permutations.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Permutations/Permutations.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Permutations.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Permutations.md new file mode 100644 index 00000000..96f3281e --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Permutations.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Permutations``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to enumerate the permutations of a sequence using `Permutations`. +[!code-csharp[](SuperLinq/Permutations/Permutations.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Permutations/Permutations.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Permutations/Permutations.linq new file mode 100644 index 00000000..cf74eba6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Permutations/Permutations.linq @@ -0,0 +1,44 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 4); + +// Partition a sequence +var result = sequence.Permutations(); + +Console.WriteLine( + $""" + [ + {string.Join(Environment.NewLine, result.Select(r => "\t[" + string.Join(", ", r) + "]"))} + ] + """); + +// This code produces the following output: +// [ +// [0, 1, 2, 3] +// [0, 1, 3, 2] +// [0, 2, 1, 3] +// [0, 2, 3, 1] +// [0, 3, 1, 2] +// [0, 3, 2, 1] +// [1, 0, 2, 3] +// [1, 0, 3, 2] +// [1, 2, 0, 3] +// [1, 2, 3, 0] +// [1, 3, 0, 2] +// [1, 3, 2, 0] +// [2, 0, 1, 3] +// [2, 0, 3, 1] +// [2, 1, 0, 3] +// [2, 1, 3, 0] +// [2, 3, 0, 1] +// [2, 3, 1, 0] +// [3, 0, 1, 2] +// [3, 0, 2, 1] +// [3, 1, 0, 2] +// [3, 1, 2, 0] +// [3, 2, 0, 1] +// [3, 2, 1, 0] +// ] diff --git a/Source/SuperLinq/Permutations.cs b/Source/SuperLinq/Permutations.cs index 807e3151..4b74b96e 100644 --- a/Source/SuperLinq/Permutations.cs +++ b/Source/SuperLinq/Permutations.cs @@ -179,21 +179,40 @@ private T[] PermuteValueSet() } /// - /// Generates a sequence of lists that represent the permutations of the original sequence. + /// Generates a sequence of lists that represent the permutations of the original sequence. /// + /// + /// The type of the elements in the sequence + /// + /// + /// The original sequence to permute + /// + /// + /// is . + /// + /// + /// has too many elements to permute properly. + /// + /// + /// A sequence of lists representing permutations of the original sequence + /// /// - /// A permutation is a unique re-ordering of the elements of the sequence.
- /// This operator returns permutations in a deferred, streaming fashion; however, each - /// permutation is materialized into a new list. There are N! permutations of a sequence, - /// where N => sequence.Count().
- /// Be aware that the original sequence is considered one of the permutations and will be - /// returned as one of the results. + /// + /// A permutation is a unique re-ordering of the elements of the sequence. + /// + /// + /// This method is implemented by using deferred execution. However, will be + /// consumed in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// + /// Each permutation is materialized into a new list. There are N! permutations of a sequence, where N is the + /// number of elements in . + /// + /// + /// Note that the original sequence is considered one of the permutations and will be returned as one of the + /// results. + /// ///
- /// The type of the elements in the sequence - /// The original sequence to permute - /// A sequence of lists representing permutations of the original sequence - /// is null. - /// has too many elements to permute properly. public static IEnumerable> Permutations(this IEnumerable sequence) { Guard.IsNotNull(sequence); From 9fcb67f044f589f89e9260b41286bf28fa7fab88 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 2 Nov 2023 12:19:31 -0500 Subject: [PATCH 067/124] Update documentation for `Pipe` --- .../apidoc/SuperLinq.SuperEnumerable.Pipe.md | 6 ++++ Source/SuperLinq/Pipe.cs | 29 +++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Pipe.md diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Pipe.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Pipe.md new file mode 100644 index 00000000..244e418a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Pipe.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Pipe``1(System.Collections.Generic.IEnumerable{``0},System.Action{``0}) +example: [*content] +--- +The following code example demonstrates how to lazily invoke actions for each element using `Do`, which is a synonym for `Pipe`. +[!code-csharp[](SuperLinq/Do/Do1.linq#L6-)] diff --git a/Source/SuperLinq/Pipe.cs b/Source/SuperLinq/Pipe.cs index d386e105..2c558901 100644 --- a/Source/SuperLinq/Pipe.cs +++ b/Source/SuperLinq/Pipe.cs @@ -3,12 +3,31 @@ public static partial class SuperEnumerable { /// - /// Lazily invokes an action for each value in the sequence. + /// Lazily invokes an action for each value in the sequence. /// - /// Source sequence element type. - /// Source sequence. - /// Action to invoke for each element. - /// Sequence exhibiting the specified side-effects upon enumeration. + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Action to invoke for each element. + /// + /// + /// Sequence exhibiting the specified side-effects upon enumeration. + /// + /// + /// or is . + /// + /// + /// + /// This method is a synonym for . + /// + /// + /// This method uses deferred execution and streams its results. + /// + /// public static IEnumerable Pipe(this IEnumerable source, Action action) { Guard.IsNotNull(source); From 1f8b60ced28e473165cf78acc772bfb4dfbacce7 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Thu, 2 Nov 2023 12:41:48 -0500 Subject: [PATCH 068/124] Update documentation for `PreScan` --- .../SuperLinq.SuperEnumerable.PreScan.md | 6 +++ .../apidoc/SuperLinq/PreScan/PreScan.linq | 17 +++++++ Source/SuperLinq/PreScan.cs | 48 +++++++++---------- 3 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PreScan.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/PreScan/PreScan.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PreScan.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PreScan.md new file mode 100644 index 00000000..ce77a26b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PreScan.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.PreScan``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0},``0) +example: [*content] +--- +The following code example demonstrates how to perform an exclusive pre-fix scan on a sequence using `PreScan`. +[!code-csharp[](SuperLinq/PreScan/PreScan1.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/PreScan/PreScan.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PreScan/PreScan.linq new file mode 100644 index 00000000..a999f9d8 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/PreScan/PreScan.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 4); + +// execute a scan of the sequence, returning the aggregation before processing the element +var result = sequence.PreScan((a, b) => a + b, 0); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [0, 1, 3, 6] diff --git a/Source/SuperLinq/PreScan.cs b/Source/SuperLinq/PreScan.cs index 2c227a32..ec861c5f 100644 --- a/Source/SuperLinq/PreScan.cs +++ b/Source/SuperLinq/PreScan.cs @@ -3,40 +3,38 @@ public static partial class SuperEnumerable { /// - /// Performs a pre-scan (exclusive prefix sum) on a sequence of elements. + /// Performs a pre-scan (exclusive prefix sum) on a sequence of elements. /// + /// + /// Type of elements in source sequence + /// + /// + /// Source sequence + /// + /// + /// An accumulator function to be invoked on each element. + /// + /// + /// The initial accumulator value. + /// + /// + /// or is . + /// + /// + /// The scanned sequence + /// /// /// - /// An exclusive prefix sum returns an equal-length sequence where the - /// N-th element is the sum of the first N-1 input elements (the first - /// element is a special case, it is set to the identity). More - /// generally, the pre-scan allows any commutative binary operation, - /// not just a sum. + /// An exclusive prefix scan returns an equal-length sequence where the N-th element is the aggregation of the + /// first N-1 input elements, where the first element is simply the value. /// /// - /// The inclusive version of PreScan is . + /// The inclusive version of PreScan is . /// /// - /// This operator uses deferred execution and streams its result. + /// This operator uses deferred execution and streams its result. /// - /// - /// a + b, 0); - /// var scan = values.Scan((a, b) => a + b); - /// ]]> - /// prescan will yield { 0, 1, 3, 6 }, while scan - /// will yield { 1, 3, 6, 10 }. This shows the relationship - /// between the inclusive and exclusive prefix sum. - /// /// - /// Type of elements in source sequence - /// Source sequence - /// Transformation operation - /// Identity element (see remarks) - /// The scanned sequence - /// is null - /// is null public static IEnumerable PreScan( this IEnumerable source, Func transformation, From 7af3e75248104afd80a7246dd1e963b13c9c4af9 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 3 Nov 2023 09:11:09 -0500 Subject: [PATCH 069/124] Update documentation for `Random` --- Source/SuperLinq/Random.cs | 224 ++++++++++++++++++++----------------- 1 file changed, 119 insertions(+), 105 deletions(-) diff --git a/Source/SuperLinq/Random.cs b/Source/SuperLinq/Random.cs index 82e87b02..19f5e33b 100644 --- a/Source/SuperLinq/Random.cs +++ b/Source/SuperLinq/Random.cs @@ -3,39 +3,38 @@ public static partial class SuperEnumerable { /// - /// Returns an infinite sequence of random integers using the standard - /// .NET random number generator. + /// Returns an infinite sequence of random integers. /// - /// An infinite sequence of random integers + /// + /// An infinite sequence of random integers + /// /// - /// The implementation internally uses a shared, thread-local instance of - /// to generate a random number on each - /// iteration. The actual instance used - /// therefore will depend on the thread on which a single iteration is - /// taking place; that is the call to - /// . If the - /// overall iteration takes place on different threads (e.g. - /// via asynchronous awaits completing on different threads) then various - /// different instances will be involved - /// in the generation of the sequence of random numbers. Because the - /// instance is shared, if multiple sequences - /// are generated on the same thread, the order of enumeration affects the - /// resulting sequences. + /// + /// This operator uses deferred execution and streams its result. + /// /// - public static IEnumerable Random() { return Random(s_randomInstance); } /// - /// Returns an infinite sequence of random integers using the supplied - /// random number generator. + /// Returns an infinite sequence of random integers using the supplied random number generator. /// - /// Random generator used to produce random numbers - /// An infinite sequence of random integers - /// Thrown if is . - + /// + /// Random generator used to produce random numbers + /// + /// + /// is . + /// + /// + /// An infinite sequence of random integers + /// + /// + /// + /// This operator uses deferred execution and streams its result. + /// + /// public static IEnumerable Random(Random rand) { Guard.IsNotNull(rand); @@ -44,27 +43,19 @@ public static IEnumerable Random(Random rand) } /// - /// Returns an infinite sequence of random integers between zero and - /// a given maximum. + /// Returns an infinite sequence of random integers between zero and a given maximum. /// - /// exclusive upper bound for the random values returned - /// An infinite sequence of random integers + /// + /// Exclusive upper bound for random values returned. + /// + /// + /// An infinite sequence of random integers + /// /// - /// The implementation internally uses a shared, thread-local instance of - /// to generate a random number on each - /// iteration. The actual instance used - /// therefore will depend on the thread on which a single iteration is - /// taking place; that is the call to - /// . If the - /// overall iteration takes place on different threads (e.g. - /// via asynchronous awaits completing on different threads) then various - /// different instances will be involved - /// in the generation of the sequence of random numbers. Because the - /// instance is shared, if multiple sequences - /// are generated on the same thread, the order of enumeration affects the - /// resulting sequences. + /// + /// This operator uses deferred execution and streams its result. + /// /// - public static IEnumerable Random(int maxValue) { Guard.IsGreaterThanOrEqualTo(maxValue, 0); @@ -73,14 +64,26 @@ public static IEnumerable Random(int maxValue) } /// - /// Returns an infinite sequence of random integers between zero and a - /// given maximum using the supplied random number generator. + /// Returns an infinite sequence of random integers between zero and a given maximum using the supplied random + /// number generator. /// - /// Random generator used to produce values - /// Exclusive upper bound for random values returned - /// An infinite sequence of random integers - /// Thrown if is . - + /// + /// Random generator used to produce values + /// + /// + /// Exclusive upper bound for random values returned + /// + /// + /// is . + /// + /// + /// An infinite sequence of random integers + /// + /// + /// + /// This operator uses deferred execution and streams its result. + /// + /// public static IEnumerable Random(Random rand, int maxValue) { Guard.IsNotNull(rand); @@ -90,43 +93,57 @@ public static IEnumerable Random(Random rand, int maxValue) } /// - /// Returns an infinite sequence of random integers between a given - /// minimum and a maximum. + /// Returns an infinite sequence of random integers between a given minimum and maximum. /// - /// Inclusive lower bound of the values returned - /// Exclusive upper bound of the values returned - /// An infinite sequence of random integers + /// + /// Inclusive lower bound for random values returned. + /// + /// + /// Exclusive upper bound for random values returned. + /// + /// + /// is greater than . + /// + /// + /// An infinite sequence of random integers + /// /// - /// The implementation internally uses a shared, thread-local instance of - /// to generate a random number on each - /// iteration. The actual instance used - /// therefore will depend on the thread on which a single iteration is - /// taking place; that is the call to - /// . If the - /// overall iteration takes place on different threads (e.g. - /// via asynchronous awaits completing on different threads) then various - /// different instances will be involved - /// in the generation of the sequence of random numbers. Because the - /// instance is shared, if multiple sequences - /// are generated on the same thread, the order of enumeration affects the - /// resulting sequences. + /// + /// This operator uses deferred execution and streams its result. + /// /// - public static IEnumerable Random(int minValue, int maxValue) { return Random(s_randomInstance, minValue, maxValue); } /// - /// Returns an infinite sequence of random integers between a given - /// minumum and a maximum using the supplied random number generator. + /// Returns an infinite sequence of random integers between zero and a given maximum using the supplied random + /// number generator. /// - /// Generator used to produce random numbers - /// Inclusive lower bound of the values returned - /// Exclusive upper bound of the values returned - /// An infinite sequence of random integers - /// Thrown if is . - /// Thrown if is greater than . + /// + /// Random generator used to produce values + /// + /// + /// Inclusive lower bound for random values returned. + /// + /// + /// Exclusive upper bound for random values returned + /// + /// + /// is . + /// + /// + /// is greater than . + /// + /// + /// An infinite sequence of random integers + /// + /// + /// + /// This operator uses deferred execution and streams its result. + /// + /// public static IEnumerable Random(Random rand, int minValue, int maxValue) { Guard.IsNotNull(rand); @@ -136,38 +153,38 @@ public static IEnumerable Random(Random rand, int minValue, int maxValue) } /// - /// Returns an infinite sequence of random double values between 0.0 and 1.0 + /// Returns an infinite sequence of random double values between 0.0 and 1.0. /// - /// An infinite sequence of random doubles + /// + /// An infinite sequence of random doubles + /// /// - /// The implementation internally uses a shared, thread-local instance of - /// to generate a random number on each - /// iteration. The actual instance used - /// therefore will depend on the thread on which a single iteration is - /// taking place; that is the call to - /// . If the - /// overall iteration takes place on different threads (e.g. - /// via asynchronous awaits completing on different threads) then various - /// different instances will be involved - /// in the generation of the sequence of random numbers. Because the - /// instance is shared, if multiple sequences - /// are generated on the same thread, the order of enumeration affects the - /// resulting sequences. + /// + /// This operator uses deferred execution and streams its result. + /// /// - public static IEnumerable RandomDouble() { return RandomDouble(s_randomInstance); } /// - /// Returns an infinite sequence of random double values between 0.0 and 1.0 - /// using the supplied random number generator. + /// Returns an infinite sequence of random double values between 0.0 and 1.0 using the supplied random number generator. /// - /// Generator used to produce random numbers - /// An infinite sequence of random doubles - /// Thrown if is . - + /// + /// Random generator used to produce values + /// + /// + /// is . + /// + /// + /// An infinite sequence of random doubles + /// + /// + /// + /// This operator uses deferred execution and streams its result. + /// + /// public static IEnumerable RandomDouble(Random rand) { Guard.IsNotNull(rand); @@ -183,7 +200,6 @@ public static IEnumerable RandomDouble(Random rand) /// Random generators used to produce the sequence /// Generator function that actually produces the next value - specific to T /// An infinite sequence of random numbers of type T - private static IEnumerable RandomImpl(Random rand, Func nextValue) { while (true) @@ -197,14 +213,12 @@ private static IEnumerable RandomImpl(Random rand, Func nextVal new GlobalRandom(); /// - /// is not thread-safe so the following - /// implementation uses thread-local - /// instances to create the illusion of a global - /// implementation. For some background, - /// see Getting - /// random numbers in a thread-safe way + /// is not thread-safe so the following implementation uses thread-local instances to create the illusion of a global + /// implementation. For some background, see Getting + /// random numbers in a thread-safe way /// - private sealed class GlobalRandom : Random { private static int s_seed = Environment.TickCount; From 998ca88c19e7074cf44a6ef8a03a8c4b8e7f7d1e Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Fri, 3 Nov 2023 09:52:42 -0500 Subject: [PATCH 070/124] Update documentation for `RandomSubset` --- .../SuperLinq.SuperEnumerable.RandomSubset.md | 13 ++++ .../SuperLinq/RandomSubset/RandomSubset1.linq | 18 +++++ .../SuperLinq/RandomSubset/RandomSubset2.linq | 17 +++++ Source/SuperLinq/RandomSubset.cs | 71 +++++++++++++------ 4 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.RandomSubset.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/RandomSubset/RandomSubset1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/RandomSubset/RandomSubset2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.RandomSubset.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.RandomSubset.md new file mode 100644 index 00000000..348755e1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.RandomSubset.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.RandomSubset``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to get a random subset of a sequence using `RandomSubset`. +[!code-csharp[](SuperLinq/RandomSubset/RandomSubset1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.RandomSubset``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Random) +example: [*content] +--- +The following code example demonstrates how to get a random subset of a sequence using `RandomSubset`. +[!code-csharp[](SuperLinq/RandomSubset/RandomSubset2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/RandomSubset/RandomSubset1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RandomSubset/RandomSubset1.linq new file mode 100644 index 00000000..06a04d05 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RandomSubset/RandomSubset1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// get a random subset of the above sequence +var result = sequence.RandomSubset(4); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible output of the above sequence: +// (each run will have different results) +// [3, 6, 7, 5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/RandomSubset/RandomSubset2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RandomSubset/RandomSubset2.linq new file mode 100644 index 00000000..0c60e0ba --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RandomSubset/RandomSubset2.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// get a random subset of the above sequence +var result = sequence.RandomSubset(4, new Random(Seed: 5)); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [7, 8, 2, 6] diff --git a/Source/SuperLinq/RandomSubset.cs b/Source/SuperLinq/RandomSubset.cs index fd805de9..1e8a3c57 100644 --- a/Source/SuperLinq/RandomSubset.cs +++ b/Source/SuperLinq/RandomSubset.cs @@ -3,49 +3,80 @@ public static partial class SuperEnumerable { /// - /// Returns a sequence of a specified size of random elements from the - /// original sequence. + /// Returns a sequence of a specified size of random elements from the original sequence. /// - /// The type of source sequence elements. + /// + /// The type of source sequence elements. + /// /// - /// The sequence from which to return random elements. - /// The size of the random subset to return. + /// The sequence from which to return random elements. + /// + /// + /// The size of the random subset to return. + /// + /// + /// is . + /// + /// + /// is negative or larger than the length of . + /// /// - /// A random sequence of elements in random order from the original - /// sequence. - + /// A random sequence of elements in random order from the original sequence. + ///
+ /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable RandomSubset(this IEnumerable source, int subsetSize) { return RandomSubset(source, subsetSize, new Random()); } /// - /// Returns a sequence of a specified size of random elements from the - /// original sequence. An additional parameter specifies a random - /// generator to be used for the random selection algorithm. + /// Returns a sequence of a specified size of random elements from the original sequence. /// - /// The type of source sequence elements. + /// + /// The type of source sequence elements. + /// /// - /// The sequence from which to return random elements. - /// The size of the random subset to return. + /// The sequence from which to return random elements. + /// + /// + /// The size of the random subset to return. + /// /// - /// A random generator used as part of the selection algorithm. + /// A random generator used as part of the selection algorithm. + /// + /// + /// or is . + /// + /// + /// is negative or larger than the length of . + /// /// - /// A random sequence of elements in random order from the original - /// sequence. - + /// A random sequence of elements in random order from the original sequence. + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable RandomSubset(this IEnumerable source, int subsetSize, Random rand) { Guard.IsNotNull(rand); Guard.IsNotNull(source); Guard.IsGreaterThanOrEqualTo(subsetSize, 0); + if (source.TryGetCollectionCount() is int n) + Guard.IsLessThanOrEqualTo(subsetSize, n); + return RandomSubsetImpl(source, rand, seq => (seq.ToArray(), subsetSize)); } -#pragma warning disable MA0050 // arguments validated in both callers private static IEnumerable RandomSubsetImpl(IEnumerable source, Random rand, Func, (T[], int)> seeder) -#pragma warning restore MA0050 { // The simplest and most efficient way to return a random subset is to perform // an in-place, partial Fisher-Yates shuffle of the sequence. While we could do From f5a9f64f73b5549c33ccbadb8ece7f7770234782 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 6 Nov 2023 08:46:22 -0600 Subject: [PATCH 071/124] Update documentation for `(Dense)Rank(By)` --- .../apidoc/SuperLinq.SuperEnumerable.Rank.md | 55 ++++ .../SuperLinq/DenseRank/DenseRank1.linq | 47 +++ .../SuperLinq/DenseRank/DenseRank3.linq | 31 ++ .../SuperLinq/DenseRankBy/DenseRankBy1.linq | 31 ++ .../SuperLinq/DenseRankBy/DenseRankBy3.linq | 32 ++ .../apidoc/SuperLinq/Rank/Rank1.linq | 47 +++ .../apidoc/SuperLinq/Rank/Rank3.linq | 31 ++ .../apidoc/SuperLinq/RankBy/RankBy1.linq | 31 ++ .../apidoc/SuperLinq/RankBy/RankBy3.linq | 32 ++ Source/SuperLinq/Rank.cs | 278 +++++++++++++----- 10 files changed, 539 insertions(+), 76 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Rank.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Rank/Rank1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Rank/Rank3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/RankBy/RankBy1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/RankBy/RankBy3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Rank.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Rank.md new file mode 100644 index 00000000..0b8624db --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Rank.md @@ -0,0 +1,55 @@ +--- +uid: SuperLinq.SuperEnumerable.DenseRank``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to rank the items in a sequence using `DenseRank`. +[!code-csharp[](SuperLinq/DenseRank/DenseRank1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DenseRank``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to rank the items in a sequence using `DenseRank`. +[!code-csharp[](SuperLinq/DenseRank/DenseRank3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DenseRankBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to rank the items in a sequence according to a key using `DenseRankBy`. +[!code-csharp[](SuperLinq/DenseRank/DenseRankBy1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.DenseRankBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to rank the items in a sequence according to a key using `DenseRankBy`. +[!code-csharp[](SuperLinq/DenseRank/DenseRankBy3.linq#L6-)] + +---- +uid: SuperLinq.SuperEnumerable.Rank``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +---- +The following code example demonstrates how to rank the items in a sequence using `Rank`. +[!code-csharp[](SuperLinq/Rank/Rank1.linq#L6-)] + +---- +uid: SuperLinq.SuperEnumerable.Rank``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IComparer{``0}) +example: [*content] +---- +The following code example demonstrates how to rank the items in a sequence using `Rank`. +[!code-csharp[](SuperLinq/Rank/Rank3.linq#L6-)] + +---- +uid: SuperLinq.SuperEnumerable.RankBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +---- +The following code example demonstrates how to rank the items in a sequence according to a key using `RankBy`. +[!code-csharp[](SuperLinq/Rank/RankBy1.linq#L6-)] + +---- +uid: SuperLinq.SuperEnumerable.RankBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IComparer{``1}) +example: [*content] +---- +The following code example demonstrates how to rank the items in a sequence according to a key using `RankBy`. +[!code-csharp[](SuperLinq/Rank/RankBy3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank1.linq new file mode 100644 index 00000000..f75865f4 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank1.linq @@ -0,0 +1,47 @@ + + SuperLinq + SuperLinq + + +var sequence = new Item[] +{ + new(key: 5, text: "1"), + new(key: 5, text: "2"), + new(key: 4, text: "3"), + new(key: 4, text: "4"), + new(key: 3, text: "5"), + new(key: 3, text: "6"), + new(key: 2, text: "7"), + new(key: 2, text: "8"), + new(key: 1, text: "9"), + new(key: 1, text: "10"), +}; + +// Rank the items in the sequence +var result = sequence.DenseRank(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [((1, 9), 1), ((1, 10), 1), ((2, 7), 2), ((2, 8), 2), ((3, 5), 3), ((3, 6), 3), ((4, 3), 4), ((4, 4), 4), ((5, 1), 5), ((5, 2), 5)] + +class Item : IComparable +{ + public Item(int key, string text) + { + Key = key; + Text = text; + } + + public int Key { get; } + public string Text { get; } + + public int CompareTo(Item other) => + this.Key.CompareTo(other.Key); + + public override string ToString() => + $"({this.Key}, {this.Text})"; +} diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank3.linq new file mode 100644 index 00000000..fdcf1b04 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank3.linq @@ -0,0 +1,31 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N sets of items +var result = sequence + .DenseRank( + Comparer<(int key, string text)>.Create((x, y) => x.key.CompareTo(y.key))); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [((1, 9), 1), ((1, 10), 1), ((2, 7), 2), ((2, 8), 2), ((3, 5), 3), ((3, 6), 3), ((4, 3), 4), ((4, 4), 4), ((5, 1), 5), ((5, 2), 5)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy1.linq new file mode 100644 index 00000000..4124f92f --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy1.linq @@ -0,0 +1,31 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N sets of items +var result = sequence + .DenseRankBy( + x => x.key); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [((1, 9), 1), ((1, 10), 1), ((2, 7), 2), ((2, 8), 2), ((3, 5), 3), ((3, 6), 3), ((4, 3), 4), ((4, 4), 4), ((5, 1), 5), ((5, 2), 5)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy3.linq new file mode 100644 index 00000000..b2ceeeff --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy3.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Get the top N sets of items +var result = sequence + .DenseRankBy( + x => x.key, + Comparer.Create((x, y) => (x % 2).CompareTo(y % 2))); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [((4, 3), 1), ((4, 4), 1), ((2, 7), 1), ((2, 8), 1), ((5, 1), 2), ((5, 2), 2), ((3, 5), 2), ((3, 6), 2), ((1, 9), 2), ((1, 10), 2)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Rank/Rank1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Rank/Rank1.linq new file mode 100644 index 00000000..48eb9ce3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Rank/Rank1.linq @@ -0,0 +1,47 @@ + + SuperLinq + SuperLinq + + +var sequence = new Item[] +{ + new(key: 5, text: "1"), + new(key: 5, text: "2"), + new(key: 4, text: "3"), + new(key: 4, text: "4"), + new(key: 3, text: "5"), + new(key: 3, text: "6"), + new(key: 2, text: "7"), + new(key: 2, text: "8"), + new(key: 1, text: "9"), + new(key: 1, text: "10"), +}; + +// Rank the items in the sequence +var result = sequence.Rank(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [((1, 9), 1), ((1, 10), 1), ((2, 7), 3), ((2, 8), 3), ((3, 5), 5), ((3, 6), 5), ((4, 3), 7), ((4, 4), 7), ((5, 1), 9), ((5, 2), 9)] + +class Item : IComparable +{ + public Item(int key, string text) + { + Key = key; + Text = text; + } + + public int Key { get; } + public string Text { get; } + + public int CompareTo(Item other) => + this.Key.CompareTo(other.Key); + + public override string ToString() => + $"({this.Key}, {this.Text})"; +} diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Rank/Rank3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Rank/Rank3.linq new file mode 100644 index 00000000..16e3b984 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Rank/Rank3.linq @@ -0,0 +1,31 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Rank the items in the sequence +var result = sequence + .Rank( + Comparer<(int key, string text)>.Create((x, y) => x.key.CompareTo(y.key))); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [((1, 9), 1), ((1, 10), 1), ((2, 7), 3), ((2, 8), 3), ((3, 5), 5), ((3, 6), 5), ((4, 3), 7), ((4, 4), 7), ((5, 1), 9), ((5, 2), 9)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/RankBy/RankBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RankBy/RankBy1.linq new file mode 100644 index 00000000..62f86d40 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RankBy/RankBy1.linq @@ -0,0 +1,31 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Rank the items in the sequence +var result = sequence + .RankBy( + x => x.key); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [((1, 9), 1), ((1, 10), 1), ((2, 7), 3), ((2, 8), 3), ((3, 5), 5), ((3, 6), 5), ((4, 3), 7), ((4, 4), 7), ((5, 1), 9), ((5, 2), 9)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/RankBy/RankBy3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RankBy/RankBy3.linq new file mode 100644 index 00000000..d43cc801 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RankBy/RankBy3.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: 5, text: "1"), + (key: 5, text: "2"), + (key: 4, text: "3"), + (key: 4, text: "4"), + (key: 3, text: "5"), + (key: 3, text: "6"), + (key: 2, text: "7"), + (key: 2, text: "8"), + (key: 1, text: "9"), + (key: 1, text: "10"), +}; + +// Rank the items in the sequence +var result = sequence + .RankBy( + x => x.key, + Comparer.Create((x, y) => (x % 2).CompareTo(y % 2))); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [((4, 3), 1), ((4, 4), 1), ((2, 7), 1), ((2, 8), 1), ((5, 1), 5), ((5, 2), 5), ((3, 5), 5), ((3, 6), 5), ((1, 9), 5), ((1, 10), 5)] diff --git a/Source/SuperLinq/Rank.cs b/Source/SuperLinq/Rank.cs index e974d9e4..0a5bbb42 100644 --- a/Source/SuperLinq/Rank.cs +++ b/Source/SuperLinq/Rank.cs @@ -3,14 +3,28 @@ public static partial class SuperEnumerable { /// - /// Ranks each item in the sequence in ascending order using a default comparer, - /// with no gaps in the ranking values. The rank of a specific item is one plus - /// the number of distinct rank values that come before that specific item. + /// Ranks each item in the sequence in ascending order using a default comparer, with no gaps in the ranking + /// values. The rank of a specific item is one plus the number of distinct rank values that come before that + /// specific item. /// - /// Type of item in the sequence - /// The sequence whose items will be ranked - /// A sorted sequence of items and their rank. - /// is . + /// + /// Type of item in the sequence + /// + /// + /// The sequence whose items will be ranked + /// + /// + /// is . + /// + /// + /// A sorted sequence of items and their rank. + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable<(TSource item, int rank)> DenseRank( this IEnumerable source) { @@ -18,15 +32,31 @@ public static partial class SuperEnumerable } /// - /// Ranks each item in the sequence in ascending order using a caller-supplied comparer, - /// with no gaps in the ranking values. The rank of a specific item is one plus - /// the number of distinct rank values that come before that specific item. + /// Ranks each item in the sequence in ascending order using a caller-supplied comparer, with no gaps in the + /// ranking values. The rank of a specific item is one plus the number of distinct rank values that come before + /// that specific item. /// - /// The type of the elements in the source sequence - /// The sequence of items to rank - /// A object that defines comparison semantics for the elements in the sequence - /// A sorted sequence of items and their rank. - /// is . + /// + /// The type of the elements in the source sequence + /// + /// + /// The sequence of items to rank + /// + /// + /// A object that defines comparison semantics for the elements in the sequence + /// + /// + /// is . + /// + /// + /// A sorted sequence of items and their rank. + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable<(TSource item, int rank)> DenseRank( this IEnumerable source, IComparer comparer) { @@ -34,18 +64,34 @@ public static partial class SuperEnumerable } /// - /// Ranks each item in the sequence in ascending order by a specified key - /// using a default comparer, with no gaps in the ranking values. The rank - /// of a specific item is one plus the number of distinct rank values that - /// come before that specific item. + /// Ranks each item in the sequence in ascending order by a specified key using a default comparer, with no gaps + /// in the ranking values. The rank of a specific item is one plus the number of distinct rank values that come + /// before that specific item. /// - /// The type of the elements in the source sequence - /// The type of the key used to rank items in the sequence - /// The sequence of items to rank - /// A key selector function which returns the value by which to rank items in the sequence - /// A sorted sequence of items and their rank. - /// is . - /// is . + /// + /// The type of the elements in the source sequence + /// + /// + /// The type of the key used to rank items in the sequence + /// + /// + /// The sequence of items to rank + /// + /// + /// A key selector function which returns the value by which to rank items in the sequence + /// + /// + /// or is . + /// + /// + /// A sorted sequence of items and their rank. + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable<(TSource item, int rank)> DenseRankBy( this IEnumerable source, Func keySelector) { @@ -56,19 +102,37 @@ public static partial class SuperEnumerable } /// - /// Ranks each item in the sequence in ascending order by a specified key - /// using a caller-supplied comparer, with no gaps in the ranking values. - /// The rank of a specific item is one plus the number of distinct rank - /// values that come before that specific item. + /// Ranks each item in the sequence in ascending order by a specified key using a caller-supplied comparer, with + /// no gaps in the ranking values. The rank of a specific item is one plus the number of distinct rank values + /// that come before that specific item. /// - /// The type of the elements in the source sequence - /// The type of the key used to rank items in the sequence - /// The sequence of items to rank - /// A key selector function which returns the value by which to rank items in the sequence - /// An object that defines the comparison semantics for keys used to rank items - /// A sorted sequence of items and their rank. - /// is . - /// is . + /// + /// The type of the elements in the source sequence + /// + /// + /// The type of the key used to rank items in the sequence + /// + /// + /// The sequence of items to rank + /// + /// + /// A key selector function which returns the value by which to rank items in the sequence + /// + /// + /// An object that defines the comparison semantics for keys used to rank items + /// + /// + /// or is . + /// + /// + /// A sorted sequence of items and their rank. + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable<(TSource item, int rank)> DenseRankBy( this IEnumerable source, Func keySelector, @@ -81,14 +145,27 @@ public static partial class SuperEnumerable } /// - /// Ranks each item in the sequence in ascending order using a default comparer. - /// The rank of a specific item is one plus the number of items that come before - /// the first item in the current equivalence set. + /// Ranks each item in the sequence in ascending order using a default comparer. The rank of a specific item is + /// one plus the number of items that come before the first item in the current equivalence set. /// - /// Type of item in the sequence - /// The sequence whose items will be ranked - /// A sorted sequence of items and their rank. - /// is . + /// + /// Type of item in the sequence + /// + /// + /// The sequence whose items will be ranked + /// + /// + /// is . + /// + /// + /// A sorted sequence of items and their rank. + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable<(TSource item, int rank)> Rank( this IEnumerable source) { @@ -96,15 +173,30 @@ public static partial class SuperEnumerable } /// - /// Ranks each item in the sequence in ascending order using a caller-supplied comparer. - /// The rank of a specific item is one plus the number of items that come before - /// the first item in the current equivalence set. + /// Ranks each item in the sequence in ascending order using a caller-supplied comparer. The rank of a specific + /// item is one plus the number of items that come before the first item in the current equivalence set. /// - /// The type of the elements in the source sequence - /// The sequence of items to rank - /// A object that defines comparison semantics for the elements in the sequence - /// A sorted sequence of items and their rank. - /// is . + /// + /// The type of the elements in the source sequence + /// + /// + /// The sequence of items to rank + /// + /// + /// A object that defines comparison semantics for the elements in the sequence + /// + /// + /// is . + /// + /// + /// A sorted sequence of items and their rank. + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable<(TSource item, int rank)> Rank( this IEnumerable source, IComparer comparer) { @@ -112,18 +204,34 @@ public static partial class SuperEnumerable } /// - /// Ranks each item in the sequence in ascending order by a specified key - /// using a default comparer. The rank of a specific item is one plus the - /// number of items that come before the first item in the current equivalence - /// set. + /// Ranks each item in the sequence in ascending order by a specified key using a default comparer. The rank of + /// a specific item is one plus the number of items that come before the first item in the current equivalence + /// set. /// - /// The type of the elements in the source sequence - /// The type of the key used to rank items in the sequence - /// The sequence of items to rank - /// A key selector function which returns the value by which to rank items in the sequence - /// A sorted sequence of items and their rank. - /// is . - /// is . + /// + /// The type of the elements in the source sequence + /// + /// + /// The type of the key used to rank items in the sequence + /// + /// + /// The sequence of items to rank + /// + /// + /// A key selector function which returns the value by which to rank items in the sequence + /// + /// + /// or is . + /// + /// + /// A sorted sequence of items and their rank. + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable<(TSource item, int rank)> RankBy( this IEnumerable source, Func keySelector) { @@ -134,19 +242,37 @@ public static partial class SuperEnumerable } /// - /// Ranks each item in the sequence in ascending order by a specified key - /// using a caller-supplied comparer. The rank of a specific item is one plus the - /// number of items that come before the first item in the current equivalence - /// set. + /// Ranks each item in the sequence in ascending order by a specified key using a caller-supplied comparer. The + /// rank of a specific item is one plus the number of items that come before the first item in the current + /// equivalence set. /// - /// The type of the elements in the source sequence - /// The type of the key used to rank items in the sequence - /// The sequence of items to rank - /// A key selector function which returns the value by which to rank items in the sequence - /// An object that defines the comparison semantics for keys used to rank items - /// A sorted sequence of items and their rank. - /// is . - /// is . + /// + /// The type of the elements in the source sequence + /// + /// + /// The type of the key used to rank items in the sequence + /// + /// + /// The sequence of items to rank + /// + /// + /// A key selector function which returns the value by which to rank items in the sequence + /// + /// + /// An object that defines the comparison semantics for keys used to rank items + /// + /// + /// or is . + /// + /// + /// A sorted sequence of items and their rank. + /// + /// + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// + /// public static IEnumerable<(TSource item, int rank)> RankBy( this IEnumerable source, Func keySelector, From 09e7a366621e49b9237d895605427c8d877ffb63 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 7 Nov 2023 08:06:18 -0600 Subject: [PATCH 072/124] Update documentation for `AggregateBy` --- .../SuperLinq.SuperEnumerable.AggregateBy.md | 13 ++++++++++++ .../SuperLinq/AggregateBy/AggregateBy1.linq | 21 +++++++++++++++++++ .../SuperLinq/AggregateBy/AggregateBy2.linq | 21 +++++++++++++++++++ Source/SuperLinq/AggregateBy.cs | 4 ++-- 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AggregateBy.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AggregateBy.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AggregateBy.md new file mode 100644 index 00000000..26361629 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.AggregateBy.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.AggregateBy``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},``2,System.Func{``2,``0,``2},System.Collections.Generic.IEqualityComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to aggregate values by key in a sequence, using `AggregateBy`. +[!code-csharp[](SuperLinq/AggregateBy/AggregateBy1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.AggregateBy``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``1,``2},System.Func{``2,``0,``2},System.Collections.Generic.IEqualityComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to aggregate values by key in a sequence, using `AggregateBy`. +[!code-csharp[](SuperLinq/AggregateBy/AggregateBy2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy1.linq new file mode 100644 index 00000000..979f80d3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy1.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 19); + +// Aggregate elements in a sequence grouped by key +var result = sequence + .AggregateBy( + x => x % 3, + 0, + (acc, e) => acc + e); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [[1, 70], [2, 57], [0, 63]] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy2.linq new file mode 100644 index 00000000..9bc4edaf --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy2.linq @@ -0,0 +1,21 @@ + + C:\Users\stuar\source\repos\viceroypenguin\SuperLinq\Source\SuperLinq\bin\Release\net7.0\SuperLinq.dll + SuperLinq + + +var sequence = Enumerable.Range(1, 19); + +// Aggregate elements in a sequence grouped by key +var result = sequence + .AggregateBy( + x => x % 3, + k => k * 1_000, + (acc, e) => acc + e); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [[1, 1070], [2, 2057], [0, 63]] diff --git a/Source/SuperLinq/AggregateBy.cs b/Source/SuperLinq/AggregateBy.cs index 06d052bd..8340e018 100644 --- a/Source/SuperLinq/AggregateBy.cs +++ b/Source/SuperLinq/AggregateBy.cs @@ -86,8 +86,8 @@ public static IEnumerable> AggregateBy is used. /// /// - /// , , or is . + /// , , , or is . /// /// /// A sequence of unique keys and their accumulated value. From 4fbecd17d8aaff664c514c1ff65b957d19779ab1 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 7 Nov 2023 14:08:04 -0600 Subject: [PATCH 073/124] Update documentation for `Publish` --- .../SuperLinq.SuperEnumerable.Publish.md | 6 +++ .../apidoc/SuperLinq/Publish/Publish1.linq | 42 +++++++++++++++++ Source/SuperLinq/Publish.cs | 46 ++++++++++--------- 3 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Publish.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Publish/Publish1.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Publish.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Publish.md new file mode 100644 index 00000000..c12c1a2c --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Publish.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Publish``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to publish multiple views of the same enumerator using `Publish`. +[!code-csharp[](SuperLinq/Publish/Publish1.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Publish/Publish1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Publish/Publish1.linq new file mode 100644 index 00000000..3085e9ca --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Publish/Publish1.linq @@ -0,0 +1,42 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 10); + +// allow multiple consumers to cache views of the same sequence +using var rng = sequence.Publish(); +using var e1 = rng.GetEnumerator(); // e1 has a view on the source starting from element 0 + +Debug.Assert(e1.MoveNext()); +Console.WriteLine("e1.MoveNext()"); +Console.WriteLine($"e1.Current: {e1.Current}"); + +Debug.Assert(e1.MoveNext()); +Console.WriteLine("e1.MoveNext()"); +Console.WriteLine($"e1.Current: {e1.Current}"); + +using var e2 = rng.GetEnumerator(); + +Debug.Assert(e2.MoveNext()); // e2 has a view on the source starting from element 2 +Console.WriteLine("e2.MoveNext()"); +Console.WriteLine($"e1.Current: {e1.Current}"); +Console.WriteLine($"e2.Current: {e2.Current}"); + +Debug.Assert(e1.MoveNext()); // e1 continues to enumerate over its view +Console.WriteLine("e1.MoveNext()"); +Console.WriteLine($"e1.Current: {e1.Current}"); +Console.WriteLine($"e2.Current: {e2.Current}"); + +// This code produces the following output: +// e1.MoveNext() +// e1.Current: 0 +// e1.MoveNext() +// e1.Current: 1 +// e2.MoveNext() +// e1.Current: 1 +// e2.Current: 2 +// e1.MoveNext() +// e1.Current: 2 +// e2.Current: 2 diff --git a/Source/SuperLinq/Publish.cs b/Source/SuperLinq/Publish.cs index e8f5d193..d112518e 100644 --- a/Source/SuperLinq/Publish.cs +++ b/Source/SuperLinq/Publish.cs @@ -6,31 +6,33 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Creates a buffer with a view over the source sequence, causing each enumerator to obtain access to the remainder - /// of the sequence from the current index in the buffer. + /// Creates a buffer with a view over the source sequence, causing each enumerator to obtain access to the + /// remainder of the sequence from the current index in the buffer. /// - /// Source sequence element type. - /// Source sequence. + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// is . + /// /// - /// Buffer enabling each enumerator to retrieve elements from the shared source sequence, starting from the index at - /// the point of obtaining the enumerator. + /// Buffer enabling each enumerator to retrieve elements from the shared source sequence, starting from the + /// index at the point of obtaining the enumerator. /// - /// is . - /// - /// - /// + /// + /// + /// A separate buffer will be maintained for each created from the returned . This buffer will be maintained until the enumerator is disposed, and will contain + /// all elements returned by from the time that the is + /// created. + /// + /// + /// This operator uses deferred execution and streams its result. + /// + /// public static IBuffer Publish(this IEnumerable source) { Guard.IsNotNull(source); From dcf69c702264f1323bb411057841648a0389455c Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 7 Nov 2023 14:52:24 -0600 Subject: [PATCH 074/124] Update documentation for `Repeat` --- .../SuperLinq.SuperEnumerable.Repeat.md | 21 +++++ .../apidoc/SuperLinq/Repeat/Repeat1.linq | 17 ++++ .../apidoc/SuperLinq/Repeat/Repeat2.linq | 19 +++++ .../apidoc/SuperLinq/Repeat/Repeat3.linq | 18 ++++ Source/SuperLinq/Repeat.cs | 82 +++++++++++++++---- 5 files changed, 139 insertions(+), 18 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Repeat.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Repeat.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Repeat.md new file mode 100644 index 00000000..aace9264 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Repeat.md @@ -0,0 +1,21 @@ +--- +uid: SuperLinq.SuperEnumerable.Repeat``1(``0) +example: [*content] +--- +The following code example demonstrates how to repeat a value using `Repeat`. +[!code-csharp[](SuperLinq/Repeat/Repeat1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Repeat``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to repeat a value using `Repeat`. +[!code-csharp[](SuperLinq/Repeat/Repeat2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Repeat``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to repeat a value using `Repeat`. +[!code-csharp[](SuperLinq/Repeat/Repeat3.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat1.linq new file mode 100644 index 00000000..83005b1e --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +// Repeat a value indefinitely +var result = SuperEnumerable + .Repeat(1) + .Take(10); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat2.linq new file mode 100644 index 00000000..c53af30d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat2.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 3); + +// Repeat a sequence indefinitely +var result = sequence + .Repeat() + .Take(10); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 1, 2, 3, 1, 2, 3, 1] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat3.linq new file mode 100644 index 00000000..c143bb27 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Repeat/Repeat3.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 3); + +// Repeat a sequence +var result = sequence + .Repeat(3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 1, 2, 3, 1, 2, 3] diff --git a/Source/SuperLinq/Repeat.cs b/Source/SuperLinq/Repeat.cs index 8160326b..8eefc155 100644 --- a/Source/SuperLinq/Repeat.cs +++ b/Source/SuperLinq/Repeat.cs @@ -3,11 +3,17 @@ public partial class SuperEnumerable { /// - /// Generates a sequence by repeating the given value infinitely. + /// Generates a sequence by repeating the given value infinitely. /// - /// Result sequence element type. - /// Value to repeat in the resulting sequence. - /// Sequence repeating the given value infinitely. + /// + /// Result sequence element type. + /// + /// + /// Value to repeat in the resulting sequence. + /// + /// + /// Sequence repeating the given value infinitely. + /// public static IEnumerable Repeat(TResult value) { while (true) @@ -15,12 +21,31 @@ public static IEnumerable Repeat(TResult value) } /// - /// Repeats and concatenates the source sequence infinitely. + /// Repeats and concatenates the source sequence infinitely. /// - /// Source sequence element type. - /// Source sequence. - /// Sequence obtained by concatenating the source sequence to itself infinitely. - /// is . + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Sequence obtained by concatenating the source sequence to itself infinitely. + /// + /// + /// is . + /// + /// + /// + /// This operator uses deferred execution and streams its result. The sequence is + /// cached as the returned is enumerated. When has + /// completed, the values from will be returned again indefinitely. + /// + /// + /// The cache is maintained separately for each generated from the returned . + /// + /// public static IEnumerable Repeat(this IEnumerable source) { Guard.IsNotNull(source); @@ -39,16 +64,37 @@ static IEnumerable Core(IEnumerable source) } /// - /// Repeats and concatenates the source sequence the given number of times. + /// Repeats and concatenates the source sequence the given number of times. /// - /// Source sequence element type. - /// Source sequence. - /// Number of times to repeat the source sequence. - /// Sequence obtained by concatenating the source sequence to itself the specified number of - /// times. - /// is . - /// is less than or equal to - /// 0. + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Number of times to repeat the source sequence. + /// + /// + /// Sequence obtained by concatenating the source sequence to itself the specified number of times. + /// + /// + /// is . + /// + /// + /// is less than or equal to 0. + /// + /// + /// + /// This operator uses deferred execution and streams its result. The sequence is + /// cached as the returned is enumerated. When has + /// completed, the values from will be returned again times. + /// + /// + /// The cache is maintained separately for each generated from the returned . + /// + /// public static IEnumerable Repeat(this IEnumerable source, int count) { Guard.IsNotNull(source); From a9919fcda682ca7b2401bff2d92efc8f10ecfb5e Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 8 Nov 2023 08:54:04 -0600 Subject: [PATCH 075/124] Update documentation for `Replace` --- .../SuperLinq.SuperEnumerable.Replace.md | 13 +++++ .../apidoc/SuperLinq/Replace/Replace1.linq | 18 ++++++ .../apidoc/SuperLinq/Replace/Replace2.linq | 18 ++++++ Source/SuperLinq/Replace.cs | 56 +++++++++++++------ 4 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Replace.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Replace/Replace1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Replace/Replace2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Replace.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Replace.md new file mode 100644 index 00000000..4f9adbfc --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Replace.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.Replace``1(System.Collections.Generic.IEnumerable{``0},System.Int32,``0) +example: [*content] +--- +The following code example demonstrates how to replace a value using `Replace`. +[!code-csharp[](SuperLinq/Replace/Replace1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Replace``1(System.Collections.Generic.IEnumerable{``0},System.Index,``0) +example: [*content] +--- +The following code example demonstrates how to replace a value using `Replace`. +[!code-csharp[](SuperLinq/Replace/Replace2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Replace/Replace1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Replace/Replace1.linq new file mode 100644 index 00000000..bddace9d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Replace/Replace1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Replace a value in a sequence +var result = sequence + .Replace(3, -100); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, -100, 5, 6, 7, 8, 9, 10] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Replace/Replace2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Replace/Replace2.linq new file mode 100644 index 00000000..794753eb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Replace/Replace2.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Replace a value in a sequence +var result = sequence + .Replace(^3, -100); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4, 5, 6, 7, -100, 9, 10] diff --git a/Source/SuperLinq/Replace.cs b/Source/SuperLinq/Replace.cs index c37d6dc1..ea24a58a 100644 --- a/Source/SuperLinq/Replace.cs +++ b/Source/SuperLinq/Replace.cs @@ -3,19 +3,29 @@ public static partial class SuperEnumerable { /// - /// Replaces a single value in a sequence at a specified index with the given replacement value. + /// Replaces a single value in a sequence at a specified index with the given replacement value. /// - /// Type of item in the sequence - /// The source sequence. - /// The index of the value to replace. - /// The replacement value to use at . + /// + /// Type of item in the sequence + /// + /// + /// The source sequence. + /// + /// + /// The index of the value to replace. + /// + /// + /// The replacement value to use at . + /// + /// + /// is . + /// /// - /// A sequence with the original values from , except for position - /// which has the value . + /// A sequence with the original values from , except for position which has the value . /// - /// is . /// - /// This operator evaluates in a deferred and streaming manner. + /// This operator evaluates in a deferred and streaming manner. /// public static IEnumerable Replace( this IEnumerable source, @@ -41,19 +51,29 @@ static IEnumerable Core( } /// - /// Replaces a single value in a sequence at a specified index with the given replacement value. + /// Replaces a single value in a sequence at a specified index with the given replacement value. /// - /// Type of item in the sequence - /// The source sequence. - /// The index of the value to replace. - /// The replacement value to use at . + /// + /// Type of item in the sequence + /// + /// + /// The source sequence. + /// + /// + /// The index of the value to replace. + /// + /// + /// The replacement value to use at . + /// + /// + /// is . + /// /// - /// A sequence with the original values from , except for position - /// which has the value . + /// A sequence with the original values from , except for position which has the value . /// - /// is . /// - /// This operator evaluates in a deferred and streaming manner. + /// This operator evaluates in a deferred and streaming manner. /// public static IEnumerable Replace( this IEnumerable source, From 6c78ab4cca4c579877e46379b3a60b23f3783d0f Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 8 Nov 2023 09:08:05 -0600 Subject: [PATCH 076/124] Update documentation for `Retry` --- .../apidoc/SuperLinq.SuperEnumerable.Retry.md | 13 ++++ .../apidoc/SuperLinq/Retry/Retry1.linq | 21 ++++++ .../apidoc/SuperLinq/Retry/Retry2.linq | 21 ++++++ Source/SuperLinq/Retry.cs | 67 ++++++++++++------- 4 files changed, 98 insertions(+), 24 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Retry.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Retry/Retry1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Retry/Retry2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Retry.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Retry.md new file mode 100644 index 00000000..307677f6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Retry.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.Retry``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to retry sequences on failure using `Retry`. +[!code-csharp[](SuperLinq/Retry/Retry1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Retry``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to retry sequences on failure using `Retry`. +[!code-csharp[](SuperLinq/Retry/Retry2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Retry/Retry1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Retry/Retry1.linq new file mode 100644 index 00000000..223fbf35 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Retry/Retry1.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +// this sequence will throw an exception on the 4th element +var sequence = Enumerable.Range(1, 3) + .Concat(SuperEnumerable.Throw(new InvalidOperationException())); + +// Re-enumerate the sequence on failure indefinitely +var result = sequence + .Retry() + .Take(12); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Retry/Retry2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Retry/Retry2.linq new file mode 100644 index 00000000..83df5908 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Retry/Retry2.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +// this sequence will throw an exception on the 4th element +var sequence = Enumerable.Range(1, 3) + .Concat(SuperEnumerable.Throw(new InvalidOperationException())); + +// Re-enumerate the sequence on failure up to n times +var result = sequence + .Retry(5) + .Take(12); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3] diff --git a/Source/SuperLinq/Retry.cs b/Source/SuperLinq/Retry.cs index b70e83dc..1b2f331b 100644 --- a/Source/SuperLinq/Retry.cs +++ b/Source/SuperLinq/Retry.cs @@ -3,20 +3,28 @@ public static partial class SuperEnumerable { /// - /// Creates a sequence that retries enumerating the source sequence as long as an error occurs. + /// Creates a sequence that retries enumerating the source sequence as long as an error occurs. /// - /// Source sequence element type. - /// Source sequence. - /// Sequence concatenating the results of the source sequence as long as an error occurs. - /// is . + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Sequence concatenating the results of the source sequence as long as an error occurs. + /// + /// + /// is . + /// /// /// - /// will be enumerated and values streamed until it either completes or encounters an - /// error. If an error is thrown, then will be re-enumerated from the beginning. This will - /// happen until an iteration of has completed without errors. + /// will be enumerated and values streamed until it either completes or encounters an + /// error. If an error is thrown, then will be re-enumerated from the beginning. This + /// will happen until an iteration of has completed without errors. /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// /// public static IEnumerable Retry(this IEnumerable source) @@ -27,26 +35,37 @@ public static IEnumerable Retry(this IEnumerable sour } /// - /// Creates a sequence that retries enumerating the source sequence as long as an error occurs, with the specified - /// maximum number of retries. + /// Creates a sequence that retries enumerating the source sequence as long as an error occurs, with the + /// specified maximum number of retries. /// - /// Source sequence element type. - /// Source sequence. - /// Maximum number of retries. - /// Sequence concatenating the results of the source sequence as long as an error occurs. - /// is . - /// is less than or equal to - /// 0. + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// Maximum number of retries. + /// + /// + /// Sequence concatenating the results of the source sequence as long as an error occurs. + /// + /// + /// is . + /// + /// + /// is less than or equal to 0. + /// /// /// - /// will be enumerated and values streamed until it either completes or encounters an - /// error. If an error is thrown, then will be re-enumerated from the beginning. This will - /// happen until an iteration of has completed without errors, or has been enumerated times. If an error is thrown during the final - /// iteration, it will not be caught and will be thrown to the consumer. + /// will be enumerated and values streamed until it either completes or encounters an + /// error. If an error is thrown, then will be re-enumerated from the beginning. This + /// will happen until an iteration of has completed without errors, or has been enumerated times. If an error is thrown during the final + /// iteration, it will not be caught and will be thrown to the consumer. /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// /// public static IEnumerable Retry(this IEnumerable source, int count) From 2aa9e5df3cdb278d7c8966256afa2a47494d13ed Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 11 Nov 2023 08:31:10 -0600 Subject: [PATCH 077/124] Update documentation for `Return` --- .../apidoc/SuperLinq.SuperEnumerable.Return.md | 6 ++++++ .../apidoc/SuperLinq/Return/Return.linq | 15 +++++++++++++++ Source/SuperLinq/Return.cs | 14 ++++++++++---- 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Return.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Return/Return.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Return.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Return.md new file mode 100644 index 00000000..23899a3a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Return.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Return``1(``0) +example: [*content] +--- +The following code example demonstrates how to return a single element as a sequence using `Return`. +[!code-csharp[](SuperLinq/Return/Return1.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Return/Return.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Return/Return.linq new file mode 100644 index 00000000..9a2a8e08 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Return/Return.linq @@ -0,0 +1,15 @@ + + SuperLinq + SuperLinq + + +// Return a sequence of a single element +var result = SuperEnumerable.Return(123); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [123] diff --git a/Source/SuperLinq/Return.cs b/Source/SuperLinq/Return.cs index 8bbfabf4..9664237b 100644 --- a/Source/SuperLinq/Return.cs +++ b/Source/SuperLinq/Return.cs @@ -5,11 +5,17 @@ namespace SuperLinq; public partial class SuperEnumerable { /// - /// Returns a single-element sequence containing the item provided. + /// Returns a single-element sequence containing the item provided. /// - /// The type of the item. - /// The item to return in a sequence. - /// A sequence containing only . + /// + /// The type of the item. + /// + /// + /// The item to return in a sequence. + /// + /// + /// A sequence containing only . + /// public static IEnumerable Return(T item) => new SingleElementList(item); From 264eab8c47751f3948e9f477a2a0207eeb0d10da Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 11 Nov 2023 08:53:36 -0600 Subject: [PATCH 078/124] Update documentation for `RunLengthEncode` --- ...perLinq.SuperEnumerable.RunLengthEncode.md | 13 +++++ .../RunLengthEncode/RunLengthEncode1.linq | 19 +++++++ .../RunLengthEncode/RunLengthEncode2.linq | 31 ++++++++++ Source/SuperLinq/RunLengthEncode.cs | 56 ++++++++++++++----- 4 files changed, 105 insertions(+), 14 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.RunLengthEncode.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/RunLengthEncode/RunLengthEncode1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/RunLengthEncode/RunLengthEncode2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.RunLengthEncode.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.RunLengthEncode.md new file mode 100644 index 00000000..6c5e4140 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.RunLengthEncode.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.RunLengthEncode``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to return the run-length-encoding of a sequence using `RunLengthEncode`. +[!code-csharp[](SuperLinq/RunLengthEncode/RunLengthEncode1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.RunLengthEncode``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to return the run-length-encoding of a sequence using `RunLengthEncode`. +[!code-csharp[](SuperLinq/RunLengthEncode/RunLengthEncode2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/RunLengthEncode/RunLengthEncode1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RunLengthEncode/RunLengthEncode1.linq new file mode 100644 index 00000000..9205be7b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RunLengthEncode/RunLengthEncode1.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Repeat(1, 3) + .Concat(Enumerable.Repeat(2, 4)) + .Concat(Enumerable.Repeat(3, 2)); + +// Get the run-length encoding of a sequence +var result = sequence.RunLengthEncode(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, 3), (2, 4), (3, 2)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/RunLengthEncode/RunLengthEncode2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RunLengthEncode/RunLengthEncode2.linq new file mode 100644 index 00000000..105c9542 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/RunLengthEncode/RunLengthEncode2.linq @@ -0,0 +1,31 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + "foo", + "FOO", + "fOo", + "bAr", + "BAR", + "BAZ", + "baz", + "Baz", + "BaZ", + "Qux", +}; + +// Get the run-length encoding of a sequence +var result = sequence + .RunLengthEncode( + StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(foo, 3), (bAr, 2), (BAZ, 4), (Qux, 1)] diff --git a/Source/SuperLinq/RunLengthEncode.cs b/Source/SuperLinq/RunLengthEncode.cs index 2586e0bb..d7c888a6 100644 --- a/Source/SuperLinq/RunLengthEncode.cs +++ b/Source/SuperLinq/RunLengthEncode.cs @@ -3,28 +3,56 @@ public static partial class SuperEnumerable { /// - /// Run-length encodes a sequence by converting consecutive instances of the same element into - /// a tuple representing the item and its occurrence count. + /// Run-length encodes a sequence by converting consecutive instances of the same element into a tuple + /// representing the item and its occurrence count. /// - /// The type of the elements in the sequence - /// The sequence to run length encode - /// A sequence of tuples containing the element and the occurrence count - + /// + /// The type of the elements in the sequence + /// + /// + /// The sequence to run length encode + /// + /// + /// is . + /// + /// + /// A sequence of tuples containing the element and the occurrence count + /// + /// + /// + /// This operator evaluates in a deferred and streaming manner. + /// + /// public static IEnumerable<(T value, int count)> RunLengthEncode(this IEnumerable sequence) { return RunLengthEncode(sequence, comparer: null); } /// - /// Run-length encodes a sequence by converting consecutive instances of the same element into - /// a tuple representing the item and its occurrence count. This overload - /// uses a custom equality comparer to identify equivalent items. + /// Run-length encodes a sequence by converting consecutive instances of the same element into a tuple + /// representing the item and its occurrence count. This overload uses a custom equality comparer to identify + /// equivalent items. /// - /// The type of the elements in the sequence - /// The sequence to run length encode - /// The comparer used to identify equivalent items - /// A sequence of tuples containing the element and the occurrence count - + /// + /// The type of the elements in the sequence + /// + /// + /// The sequence to run length encode + /// + /// + /// The comparer used to identify equivalent items + /// + /// + /// is . + /// + /// + /// A sequence of tuples containing the element and the occurrence count + /// + /// + /// + /// This operator evaluates in a deferred and streaming manner. + /// + /// public static IEnumerable<(T value, int count)> RunLengthEncode(this IEnumerable sequence, IEqualityComparer? comparer) { Guard.IsNotNull(sequence); From 8c193e2c8b61c459963620f25d1fce3606656ceb Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 11 Nov 2023 15:38:35 -0600 Subject: [PATCH 079/124] Update documentation for `Scan` --- .../apidoc/SuperLinq.SuperEnumerable.Scan.md | 13 ++ .../apidoc/SuperLinq/Scan/Scan1.linq | 17 +++ .../apidoc/SuperLinq/Scan/Scan2.linq | 20 +++ Source/SuperLinq/Scan.cs | 140 ++++++++++++------ 4 files changed, 146 insertions(+), 44 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Scan.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Scan/Scan1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Scan/Scan2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Scan.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Scan.md new file mode 100644 index 00000000..702130fd --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Scan.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.Scan``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0}) +example: [*content] +--- +The following code example demonstrates how to execute a post-fix scan on a sequence using `Scan`. +[!code-csharp[](SuperLinq/Scan/Scan1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Scan``2(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``1,``0,``1}) +example: [*content] +--- +The following code example demonstrates how to execute a post-fix scan on a sequence using `Scan`. +[!code-csharp[](SuperLinq/Scan/Scan2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Scan/Scan1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Scan/Scan1.linq new file mode 100644 index 00000000..38938c26 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Scan/Scan1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 4); + +// execute a scan of the sequence +var result = sequence.Scan((a, b) => a + b); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 3, 6, 10] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Scan/Scan2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Scan/Scan2.linq new file mode 100644 index 00000000..c6d21d89 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Scan/Scan2.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 4); + +// execute a scan of the sequence +var result = sequence + .Scan( + "0", + (a, b) => $"({a} + {b})"); + +Console.WriteLine( + "[ \"" + + string.Join("\", \"", result) + + "\" ]"); + +// This code produces the following output: +// [ "0", "(0 + 1)", "((0 + 1) + 2)", "(((0 + 1) + 2) + 3)", "((((0 + 1) + 2) + 3) + 4)" ] diff --git a/Source/SuperLinq/Scan.cs b/Source/SuperLinq/Scan.cs index 372a2635..e1e9a910 100644 --- a/Source/SuperLinq/Scan.cs +++ b/Source/SuperLinq/Scan.cs @@ -3,18 +3,29 @@ public static partial class SuperEnumerable { /// - /// Performs a scan (inclusive prefix sum) on a sequence of elements. This operator is similar to except that returns the sequence of - /// intermediate results as well as the final one. + /// Performs a scan (inclusive prefix sum) on a sequence of elements. This operator is similar to except that returns the sequence of + /// intermediate results as well as the final one. /// - /// Type of elements in source sequence - /// Source sequence - /// Transformation operation - /// The scanned sequence - /// or is . + /// + /// Type of elements in source sequence + /// + /// + /// Source sequence + /// + /// + /// Transformation operation + /// + /// + /// The scanned sequence + /// + /// + /// or is . + /// /// - /// This operator uses deferred execution and streams its result. + /// + /// This operator uses deferred execution and streams its result. + /// /// public static IEnumerable Scan( this IEnumerable source, @@ -44,18 +55,29 @@ static IEnumerable Core(IEnumerable source, Func - /// Performs a scan (inclusive prefix sum) on a sequence of elements. This operator is similar to except that returns the sequence of - /// intermediate results as well as the final one. + /// Performs a scan (inclusive prefix sum) on a sequence of elements. This operator is similar to except that returns the sequence of + /// intermediate results as well as the final one. /// - /// Type of elements in source sequence - /// Source sequence - /// Transformation operation - /// The scanned sequence - /// or is . + /// + /// Type of elements in source sequence + /// + /// + /// Source sequence + /// + /// + /// Transformation operation + /// + /// + /// The scanned sequence + /// + /// + /// or is . + /// /// - /// This operator uses deferred execution and streams its result. + /// + /// This operator uses deferred execution and streams its result. + /// /// [Obsolete("Method renamed back to `Scan`.")] public static IEnumerable ScanEx( @@ -66,20 +88,35 @@ public static IEnumerable ScanEx( } /// - /// Performs a scan (inclusive prefix sum) on a sequence of elements. This operator is similar to except that returns the - /// sequence of intermediate results as well as the final one. + /// Performs a scan (inclusive prefix sum) on a sequence of elements. This operator is similar to except that returns the sequence of + /// intermediate results as well as the final one. /// - /// Type of elements in source sequence - /// Type of state - /// Source sequence - /// Initial state to seed - /// Transformation operation - /// The scanned sequence - /// or is . + /// + /// Type of elements in source sequence + /// + /// + /// Type of state + /// + /// + /// Source sequence + /// + /// + /// Initial state to seed + /// + /// + /// Transformation operation + /// + /// + /// The scanned sequence + /// + /// + /// or is . + /// /// - /// This operator uses deferred execution and streams its result. + /// + /// This operator uses deferred execution and streams its result. + /// /// public static IEnumerable Scan( this IEnumerable source, @@ -107,20 +144,35 @@ static IEnumerable Core( } /// - /// Performs a scan (inclusive prefix sum) on a sequence of elements. This operator is similar to except that returns the - /// sequence of intermediate results as well as the final one. + /// Performs a scan (inclusive prefix sum) on a sequence of elements. This operator is similar to except that returns the sequence of + /// intermediate results as well as the final one. /// - /// Type of elements in source sequence - /// Type of state - /// Source sequence - /// Initial state to seed - /// Transformation operation - /// The scanned sequence - /// or is . + /// + /// Type of elements in source sequence + /// + /// + /// Type of state + /// + /// + /// Source sequence + /// + /// + /// Initial state to seed + /// + /// + /// Transformation operation + /// + /// + /// The scanned sequence + /// + /// + /// or is . + /// /// - /// This operator uses deferred execution and streams its result. + /// + /// This operator uses deferred execution and streams its result. + /// /// [Obsolete("Method renamed back to `Scan`.")] public static IEnumerable ScanEx( From 0af9a7ee6d1992c0c0073209eebb56142b941fe0 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 11 Nov 2023 16:11:35 -0600 Subject: [PATCH 080/124] Update documentation for `ScanBy` --- .../SuperLinq.SuperEnumerable.ScanBy.md | 13 +++ .../apidoc/SuperLinq/ScanBy/ScanBy1.linq | 21 ++++ .../apidoc/SuperLinq/ScanBy/ScanBy2.linq | 34 +++++++ Source/SuperLinq/ScanBy.cs | 98 ++++++++++++------- 4 files changed, 132 insertions(+), 34 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanBy.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanBy/ScanBy1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanBy/ScanBy2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanBy.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanBy.md new file mode 100644 index 00000000..51add0b5 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanBy.md @@ -0,0 +1,13 @@ +--- +uid: ScanBy``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``1,``2},System.Func{``2,``1,``0,``2}) +example: [*content] +--- +The following code example demonstrates how to execute a post-fix scan by key on a sequence using `ScanBy`. +[!code-csharp[](SuperLinq/ScanBy/ScanBy1.linq#L6-)] + +--- +uid: ScanBy``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``1,``2},System.Func{``2,``1,``0,``2},System.Collections.Generic.IEqualityComparer{``1}) +example: [*content] +--- +The following code example demonstrates how to execute a post-fix scan by key on a sequence using `ScanBy`. +[!code-csharp[](SuperLinq/ScanBy/ScanBy2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanBy/ScanBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanBy/ScanBy1.linq new file mode 100644 index 00000000..aca070f6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanBy/ScanBy1.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// execute a scan of the sequence +var result = sequence + .ScanBy( + x => x % 2, + k => k * 1000, + (a, k, b) => a + b); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, 1001), (0, 2), (1, 1004), (0, 6), (1, 1009), (0, 12), (1, 1016), (0, 20), (1, 1025), (0, 30)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanBy/ScanBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanBy/ScanBy2.linq new file mode 100644 index 00000000..cb5da612 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanBy/ScanBy2.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + "BAR", + "foo", + "Baz", + "Qux", + "BAZ", + "FOO", + "bAr", + "baz", + "fOo", + "BaZ", +}; + +// execute a scan of the sequence +var result = sequence + .ScanBy( + x => x[..1], + k => 0, + (a, k, b) => a + 1, + StringComparer.OrdinalIgnoreCase); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(B, 1), (f, 1), (B, 2), (Q, 1), (B, 3), (F, 2), (b, 4), (b, 5), (f, 3), (B, 6)] diff --git a/Source/SuperLinq/ScanBy.cs b/Source/SuperLinq/ScanBy.cs index 29f3b367..86b3d769 100644 --- a/Source/SuperLinq/ScanBy.cs +++ b/Source/SuperLinq/ScanBy.cs @@ -3,27 +3,42 @@ public static partial class SuperEnumerable { /// - /// Applies an accumulator function over sequence element keys, - /// returning the keys along with intermediate accumulator states. + /// Applies an accumulator function over sequence element keys, returning the keys along with intermediate + /// accumulator states. /// - /// Type of the elements of the source sequence. - /// The type of the key. - /// Type of the state. - /// The source sequence. + /// + /// Type of the elements of the source sequence. + /// + /// + /// The type of the key. + /// + /// + /// Type of the state. + /// + /// + /// The source sequence. + /// /// - /// A function that returns the key given an element. + /// A function that returns the key given an element. + /// /// - /// A function to determine the initial value for the accumulator that is - /// invoked once per key encountered. + /// A function to determine the initial value for the accumulator that is invoked once per key encountered. + /// /// - /// An accumulator function invoked for each element. + /// An accumulator function invoked for each element. + /// + /// + /// , , , or is . + /// /// - /// A sequence of keys paired with intermediate accumulator states. + /// A sequence of keys paired with intermediate accumulator states. /// - /// is . - /// is . - /// is . - /// is . + /// + /// + /// This operator uses deferred execution and streams its result. + /// + /// public static IEnumerable<(TKey key, TState state)> ScanBy( this IEnumerable source, Func keySelector, @@ -34,31 +49,46 @@ public static partial class SuperEnumerable } /// - /// Applies an accumulator function over sequence element keys, - /// returning the keys along with intermediate accumulator states. An - /// additional parameter specifies the comparer to use to compare keys. + /// Applies an accumulator function over sequence element keys, returning the keys along with intermediate + /// accumulator states. /// - /// Type of the elements of the source sequence. - /// The type of the key. - /// Type of the state. - /// The source sequence. + /// + /// Type of the elements of the source sequence. + /// + /// + /// The type of the key. + /// + /// + /// Type of the state. + /// + /// + /// The source sequence. + /// /// - /// A function that returns the key given an element. + /// A function that returns the key given an element. + /// /// - /// A function to determine the initial value for the accumulator that is - /// invoked once per key encountered. + /// A function to determine the initial value for the accumulator that is invoked once per key encountered. + /// /// - /// An accumulator function invoked for each element. - /// The equality comparer to use to determine - /// whether or not keys are equal. If , the default equality - /// comparer for is used. + /// An accumulator function invoked for each element. + /// + /// + /// The equality comparer to use to determine whether or not keys are equal. If , the + /// default equality comparer for is used. + /// + /// + /// , , , or is . + /// /// - /// A sequence of keys paired with intermediate accumulator states. + /// A sequence of keys paired with intermediate accumulator states. /// - /// is . - /// is . - /// is . - /// is . + /// + /// + /// This operator uses deferred execution and streams its result. + /// + /// public static IEnumerable<(TKey key, TState state)> ScanBy( this IEnumerable source, Func keySelector, From 3ab1d76c881f730066ce509799be6c82b4a35a18 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 11 Nov 2023 16:41:48 -0600 Subject: [PATCH 081/124] Update documentation for `ScanRight` --- .../SuperLinq.SuperEnumerable.ScanRight.md | 13 +++ .../SuperLinq/ScanRight/ScanRight1.linq | 19 ++++ .../SuperLinq/ScanRight/ScanRight2.linq | 20 +++++ Source/SuperLinq/ScanRight.cs | 89 +++++++++++-------- 4 files changed, 102 insertions(+), 39 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanRight.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanRight/ScanRight1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanRight/ScanRight2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanRight.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanRight.md new file mode 100644 index 00000000..a755deba --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanRight.md @@ -0,0 +1,13 @@ +--- +uid: ScanRight``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0}) +example: [*content] +--- +The following code example demonstrates how to execute a right-associative post-fix scan by key on a sequence using `ScanRight`. +[!code-csharp[](SuperLinq/ScanBy/ScanBy1.linq#L6-)] + +--- +uid: ScanRight``2(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``0,``1,``1}) +example: [*content] +--- +The following code example demonstrates how to execute a right-associative post-fix scan by key on a sequence using `ScanRight`. +[!code-csharp[](SuperLinq/ScanBy/ScanBy2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanRight/ScanRight1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanRight/ScanRight1.linq new file mode 100644 index 00000000..f3bef9dc --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanRight/ScanRight1.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5) + .Select(x => x.ToString()); + +// execute a scan of the sequence +var result = sequence + .ScanRight((a, b) => $"({a}+{b})"); + +Console.WriteLine( + "[ \"" + + string.Join("\", \"", result) + + "\" ]"); + +// This code produces the following output: +// [ "(1+(2+(3+(4+5))))", "(2+(3+(4+5)))", "(3+(4+5))", "(4+5)", "5" ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanRight/ScanRight2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanRight/ScanRight2.linq new file mode 100644 index 00000000..a9e2ffa3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ScanRight/ScanRight2.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// execute a scan of the sequence +var result = sequence + .ScanRight( + "6", + (a, b) => $"({a}+{b})"); + +Console.WriteLine( + "[ \"" + + string.Join("\", \"", result) + + "\" ]"); + +// This code produces the following output: +// [ "(1+(2+(3+(4+(5+6)))))", "(2+(3+(4+(5+6))))", "(3+(4+(5+6)))", "(4+(5+6))", "(5+6)", "6" ] diff --git a/Source/SuperLinq/ScanRight.cs b/Source/SuperLinq/ScanRight.cs index 8305b8b9..c688899a 100644 --- a/Source/SuperLinq/ScanRight.cs +++ b/Source/SuperLinq/ScanRight.cs @@ -5,28 +5,31 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Performs a right-associative scan (inclusive prefix) on a sequence of elements. - /// This operator is the right-associative version of the - /// LINQ operator. + /// Performs a right-associative scan (inclusive prefix) on a sequence of elements. This operator is the + /// right-associative version of the LINQ operator. /// - /// Type of elements in source sequence. - /// Source sequence. + /// + /// Type of elements in source sequence. + /// + /// + /// Source sequence. + /// /// - /// A right-associative accumulator function to be invoked on each element. - /// Its first argument is the current value in the sequence; second argument is the previous accumulator value. + /// A right-associative accumulator function to be invoked on each element. Its first argument is the current + /// value in the sequence; second argument is the previous accumulator value. /// - /// The scanned sequence. - /// is . - /// is . - /// - /// i.ToString()).ScanRight((a, b) => $"({a}+{b})"); - /// ]]> - /// The result variable will contain [ "(1+(2+(3+(4+5))))", "(2+(3+(4+5)))", "(3+(4+5))", "(4+5)", "5" ]. - /// + /// + /// The scanned sequence. + /// + /// + /// or is . + /// /// - /// This operator uses deferred execution and streams its results. - /// Source sequence is consumed greedily when an iteration of the resulting sequence begins. + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// /// public static IEnumerable ScanRight(this IEnumerable source, Func func) { @@ -99,29 +102,37 @@ public override void CopyTo(T[] array, int arrayIndex) } /// - /// Performs a right-associative scan (inclusive prefix) on a sequence of elements. - /// The specified seed value is used as the initial accumulator value. - /// This operator is the right-associative version of the - /// LINQ operator. + /// Performs a right-associative scan (inclusive prefix) on a sequence of elements. This operator is the + /// right-associative version of the LINQ operator. /// - /// The type of the elements of source. - /// The type of the accumulator value. - /// Source sequence. - /// The initial accumulator value. - /// A right-associative accumulator function to be invoked on each element. - /// The scanned sequence. - /// is . - /// is . - /// is . - /// - /// string.Format("({0}/{1})", a, b)); - /// ]]> - /// The result variable will contain [ "(1+(2+(3+(4+5))))", "(2+(3+(4+5)))", "(3+(4+5))", "(4+5)", "5" ]. - /// + /// + /// Type of elements in source sequence. + /// + /// + /// Type of the state accumulator. + /// + /// + /// Source sequence. + /// + /// + /// A right-associative accumulator function to be invoked on each element. Its first argument is the current + /// value in the sequence; second argument is the previous accumulator value. + /// + /// + /// The initial accumulator value. + /// + /// + /// The scanned sequence. + /// + /// + /// or is . + /// /// - /// This operator uses deferred execution and streams its results. - /// Source sequence is consumed greedily when an iteration of the resulting sequence begins. + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// /// public static IEnumerable ScanRight(this IEnumerable source, TAccumulate seed, Func func) { From f31a2630f5f86411d52e458f4e8f002b90d337ab Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Sat, 11 Nov 2023 18:34:45 -0600 Subject: [PATCH 082/124] Update documentation for `Segment` --- .../SuperLinq.SuperEnumerable.Segment.md | 21 +++++ .../apidoc/SuperLinq/Segment/Segment1.linq | 38 ++++++++ .../apidoc/SuperLinq/Segment/Segment2.linq | 40 +++++++++ .../apidoc/SuperLinq/Segment/Segment3.linq | 40 +++++++++ Source/SuperLinq/Segment.cs | 87 ++++++++++++++----- 5 files changed, 205 insertions(+), 21 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Segment.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment3.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Segment.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Segment.md new file mode 100644 index 00000000..a7239fb7 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Segment.md @@ -0,0 +1,21 @@ +--- +uid: SuperLinq.SuperEnumerable.Segment``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a segment detector using `Segment`. +[!code-csharp[](SuperLinq/Segment/Segment1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Segment``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Int32,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a segment detector using `Segment`. +[!code-csharp[](SuperLinq/Segment/Segment2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Segment``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,System.Int32,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a segment detector using `Segment`. +[!code-csharp[](SuperLinq/Segment/Segment3.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment1.linq new file mode 100644 index 00000000..427c9303 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment1.linq @@ -0,0 +1,38 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 789), + (key: "feb", value: 987), + (key: "Feb", value: 654), + (key: "FEB", value: 321), + (key: "mar", value: 789), + (key: "Mar", value: 456), + (key: "MAR", value: 123), + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 781), +}; + +// Group adjacent items +var result = sequence + .Segment( + x => x.key[0] == 'm'); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [(jan, 123), (Jan, 456), (JAN, 789), (feb, 987), (Feb, 654), (FEB, 321)], +// [(mar, 789), (Mar, 456), (MAR, 123), (jan, 123), (Jan, 456), (JAN, 781)] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment2.linq new file mode 100644 index 00000000..5d750125 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment2.linq @@ -0,0 +1,40 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 789), + (key: "feb", value: 987), + (key: "Feb", value: 654), + (key: "FEB", value: 321), + (key: "mar", value: 789), + (key: "Mar", value: 456), + (key: "MAR", value: 123), + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 781), +}; + +// Group adjacent items +var result = sequence + .Segment( + (x, i) => i % 3 == 0); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [(jan, 123), (Jan, 456), (JAN, 789)], +// [(feb, 987), (Feb, 654), (FEB, 321)], +// [(mar, 789), (Mar, 456), (MAR, 123)], +// [(jan, 123), (Jan, 456), (JAN, 781)] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment3.linq new file mode 100644 index 00000000..a0d20487 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Segment/Segment3.linq @@ -0,0 +1,40 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 789), + (key: "feb", value: 987), + (key: "Feb", value: 654), + (key: "FEB", value: 321), + (key: "mar", value: 789), + (key: "Mar", value: 456), + (key: "MAR", value: 123), + (key: "jan", value: 123), + (key: "Jan", value: 456), + (key: "JAN", value: 781), +}; + +// Group adjacent items +var result = sequence + .Segment( + (cur, prev, i) => !string.Equals(cur.key[..1], prev.key[..1], StringComparison.OrdinalIgnoreCase)); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [(jan, 123), (Jan, 456), (JAN, 789)], +// [(feb, 987), (Feb, 654), (FEB, 321)], +// [(mar, 789), (Mar, 456), (MAR, 123)], +// [(jan, 123), (Jan, 456), (JAN, 781)] +// ] diff --git a/Source/SuperLinq/Segment.cs b/Source/SuperLinq/Segment.cs index 483a9bdd..f944eb07 100644 --- a/Source/SuperLinq/Segment.cs +++ b/Source/SuperLinq/Segment.cs @@ -3,16 +3,31 @@ public static partial class SuperEnumerable { /// - /// Divides a sequence into multiple sequences by using a segment detector based on the original sequence + /// Divides a sequence into multiple sequences by using a segment detector based on the original sequence /// - /// The type of the elements in the sequence - /// The sequence to segment - /// A function, which returns if the given element begins a new segment, and otherwise - /// A sequence of segment, each of which is a portion of the original sequence + /// + /// The type of the elements in the sequence + /// + /// + /// The sequence to segment + /// + /// + /// A function, which returns if the given element begins a new segment, and otherwise + /// /// - /// Thrown if either or are . + /// or is . /// - + /// + /// A sequence of segment, each of which is a portion of the original sequence + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable> Segment(this IEnumerable source, Func newSegmentPredicate) { Guard.IsNotNull(newSegmentPredicate); @@ -21,16 +36,31 @@ public static IEnumerable> Segment(this IEnumerable source, } /// - /// Divides a sequence into multiple sequences by using a segment detector based on the original sequence + /// Divides a sequence into multiple sequences by using a segment detector based on the original sequence /// - /// The type of the elements in the sequence - /// The sequence to segment - /// A function, which returns if the given element or index indicate a new segment, and otherwise - /// A sequence of segment, each of which is a portion of the original sequence + /// + /// The type of the elements in the sequence + /// + /// + /// The sequence to segment + /// + /// + /// A function, which returns if the given element and index begins a new segment, and + /// otherwise + /// /// - /// Thrown if either or are . + /// or is . /// - + /// + /// A sequence of segment, each of which is a portion of the original sequence + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable> Segment(this IEnumerable source, Func newSegmentPredicate) { Guard.IsNotNull(newSegmentPredicate); @@ -39,16 +69,31 @@ public static IEnumerable> Segment(this IEnumerable source, } /// - /// Divides a sequence into multiple sequences by using a segment detector based on the original sequence + /// Divides a sequence into multiple sequences by using a segment detector based on the original sequence /// - /// The type of the elements in the sequence - /// The sequence to segment - /// A function, which returns if the given current element, previous element or index indicate a new segment, and otherwise - /// A sequence of segment, each of which is a portion of the original sequence + /// + /// The type of the elements in the sequence + /// + /// + /// The sequence to segment + /// + /// + /// A function, which returns if the given current element, previous element, and index + /// begins a new segment, and otherwise + /// /// - /// Thrown if either or are . + /// or is . /// - + /// + /// A sequence of segment, each of which is a portion of the original sequence + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable> Segment(this IEnumerable source, Func newSegmentPredicate) { Guard.IsNotNull(source); From 9985616cb0c2be5194c06025b3775a494a2c4399 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 13 Nov 2023 11:33:18 -0600 Subject: [PATCH 083/124] Update documentation for `Sequence` --- .../SuperLinq.SuperEnumerable.Sequence.md | 20 ++++ .../apidoc/SuperLinq/Range/Range.linq | 16 ++++ .../apidoc/SuperLinq/Sequence/Sequence1.linq | 25 +++++ .../apidoc/SuperLinq/Sequence/Sequence2.linq | 25 +++++ Source/SuperLinq/Sequence.cs | 91 +++++++++++-------- 5 files changed, 140 insertions(+), 37 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Sequence.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Range/Range.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Sequence/Sequence1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Sequence/Sequence2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Sequence.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Sequence.md new file mode 100644 index 00000000..613a90cf --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Sequence.md @@ -0,0 +1,20 @@ +--- +uid: SuperLinq.SuperEnumerable.Range(System.Int32,System.Int32,System.Int32) +example: [*content] +--- +The following code example demonstrates how to generate a sequence of values using `Range`. +[!code-csharp[](SuperLinq/Range/Range.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Sequence(System.Int32,System.Int32) +example: [*content] +--- +The following code example demonstrates how to generate a sequence of values using `Sequence`. +[!code-csharp[](SuperLinq/Sequence/Sequence1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Sequence(System.Int32,System.Int32,System.Int32) +example: [*content] +--- +The following code example demonstrates how to generate a sequence of values using `Sequence`. +[!code-csharp[](SuperLinq/Sequence/Sequence2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Range/Range.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Range/Range.linq new file mode 100644 index 00000000..11a19bc5 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Range/Range.linq @@ -0,0 +1,16 @@ + + SuperLinq + SuperLinq + + +// Generate a sequence using a sequence function +var result = SuperEnumerable + .Range(1, 10, 2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Sequence/Sequence1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Sequence/Sequence1.linq new file mode 100644 index 00000000..cc0df2c2 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Sequence/Sequence1.linq @@ -0,0 +1,25 @@ + + SuperLinq + SuperLinq + + +// Generate a sequence using a sequence function +var result = SuperEnumerable + .Sequence(5, 10); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +result = SuperEnumerable + .Sequence(10, 5); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [5, 6, 7, 8, 9, 10] +// [10, 9, 8, 7, 6, 5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Sequence/Sequence2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Sequence/Sequence2.linq new file mode 100644 index 00000000..02c5b0c3 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Sequence/Sequence2.linq @@ -0,0 +1,25 @@ + + SuperLinq + SuperLinq + + +// Generate a sequence using a sequence function +var result = SuperEnumerable + .Sequence(5, 10, 2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +result = SuperEnumerable + .Sequence(10, 5, -2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [5, 7, 9] +// [10, 8, 6] diff --git a/Source/SuperLinq/Sequence.cs b/Source/SuperLinq/Sequence.cs index 06fa25ce..41399724 100644 --- a/Source/SuperLinq/Sequence.cs +++ b/Source/SuperLinq/Sequence.cs @@ -2,18 +2,30 @@ public static partial class SuperEnumerable { - /// Generates a sequence of integral numbers within a specified range. - /// The value of the first integer in the sequence. - /// The number of sequential integers to generate. - /// The step increment for each returned value. - /// - /// An that contains - /// a range of sequential integral numbers. - /// + /// + /// Generates a sequence of integral numbers within a specified range. + /// + /// + /// The value of the first integer in the sequence. + /// + /// + /// The number of sequential integers to generate. + /// + /// + /// The step increment for each returned value. + /// /// - /// is less than 0. -or- + ( -1) * - /// cannot be contained by an . + /// is less than 0. -or- + ( -1) * + /// cannot be contained by an . /// + /// + /// An that contains a range of sequential integral numbers. + /// + /// + /// + /// This operator uses deferred execution and streams its results. + /// + /// public static IEnumerable Range(int start, int count, int step) { Guard.IsGreaterThanOrEqualTo(count, 0); @@ -25,45 +37,50 @@ public static IEnumerable Range(int start, int count, int step) } /// - /// Generates a sequence of integral numbers within the (inclusive) specified range. - /// If sequence is ascending the step is +1, otherwise -1. + /// Generates a sequence of integral numbers within the (inclusive) specified range. If sequence is ascending + /// the step is +1, otherwise -1. /// - /// The value of the first integer in the sequence. - /// The value of the last integer in the sequence. - /// An that contains a range of sequential integral numbers. + /// + /// The value of the first integer in the sequence. + /// + /// + /// The value of the last integer in the sequence. + /// + /// + /// An that contains a range of sequential integral numbers. + /// /// - /// This operator uses deferred execution and streams its results. + /// + /// This operator uses deferred execution and streams its results. + /// /// - /// - /// - /// The result variable will contain { 6, 5, 4, 3, 2, 1, 0 }. - /// public static IEnumerable Sequence(int start, int stop) { return new SequenceIterator(start, start <= stop ? 1 : -1, Math.Abs((long)stop - start) + 1); } /// - /// Generates a sequence of integral numbers within the (inclusive) specified range. - /// An additional parameter specifies the steps in which the integers of the sequence increase or decrease. + /// Generates a sequence of integral numbers within the (inclusive) specified range. An additional parameter + /// specifies the steps in which the integers of the sequence increase or decrease. /// - /// The value of the first integer in the sequence. - /// The value of the last integer in the sequence. - /// The step to define the next number. - /// An that contains a range of sequential integral numbers. + /// + /// The value of the first integer in the sequence. + /// + /// + /// The value of the last integer in the sequence. + /// + /// + /// The step to define the next number. + /// + /// + /// An that contains a range of sequential integral numbers. + /// /// - /// When is equal to zero, this operator returns an - /// infinite sequence where all elements are equals to . - /// This operator uses deferred execution and streams its results. + /// + /// When is equal to zero, this operator returns an infinite sequence where all elements + /// are equals to . This operator uses deferred execution and streams its results. + /// /// - /// - /// - /// The result variable will contain { 6, 4, 2, 0 }. - /// public static IEnumerable Sequence(int start, int stop, int step) { if (step == 0) From 0ad74ca05e1439e37ef070feeb9ca488c76a546d Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 13 Nov 2023 12:17:49 -0600 Subject: [PATCH 084/124] Update documentation for `Share` --- .../apidoc/SuperLinq.SuperEnumerable.Share.md | 6 +++ .../apidoc/SuperLinq/Share/Share.linq | 42 +++++++++++++++++++ Source/SuperLinq/Share.cs | 40 +++++++++--------- 3 files changed, 67 insertions(+), 21 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Share.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Share/Share.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Share.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Share.md new file mode 100644 index 00000000..890a5853 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Share.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Share``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to share a single view of an enumerator across multiple consumers using `Share`. +[!code-csharp[](SuperLinq/Share/Share.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Share/Share.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Share/Share.linq new file mode 100644 index 00000000..7ce43201 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Share/Share.linq @@ -0,0 +1,42 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 10); + +// allow multiple consumers to cache views of the same sequence +using var rng = sequence.Share(); +using var e1 = rng.GetEnumerator(); // e1 has a shared view on the source + +Debug.Assert(e1.MoveNext()); +Console.WriteLine("e1.MoveNext()"); +Console.WriteLine($"e1.Current: {e1.Current}"); + +Debug.Assert(e1.MoveNext()); +Console.WriteLine("e1.MoveNext()"); +Console.WriteLine($"e1.Current: {e1.Current}"); + +using var e2 = rng.GetEnumerator(); // e2 has a shared view on the source + +Debug.Assert(e2.MoveNext()); // e2 enumerates over the shared view, advancing the source +Console.WriteLine("e2.MoveNext()"); +Console.WriteLine($"e1.Current: {e1.Current}"); +Console.WriteLine($"e2.Current: {e2.Current}"); + +Debug.Assert(e1.MoveNext()); // e1 enumerates over the shared view, advancing the source +Console.WriteLine("e1.MoveNext()"); +Console.WriteLine($"e1.Current: {e1.Current}"); +Console.WriteLine($"e2.Current: {e2.Current}"); + +// This code produces the following output: +// e1.MoveNext() +// e1.Current: 0 +// e1.MoveNext() +// e1.Current: 1 +// e2.MoveNext() +// e1.Current: 1 +// e2.Current: 2 +// e1.MoveNext() +// e1.Current: 3 +// e2.Current: 2 diff --git a/Source/SuperLinq/Share.cs b/Source/SuperLinq/Share.cs index ef02c4d2..2f1229ce 100644 --- a/Source/SuperLinq/Share.cs +++ b/Source/SuperLinq/Share.cs @@ -6,28 +6,26 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Creates a buffer with a shared view over the source sequence, causing each enumerator to fetch the next element - /// from the source sequence. + /// Creates a buffer with a shared view over the source sequence, causing each enumerator to fetch the next + /// element from the source sequence. /// - /// Source sequence element type. - /// Source sequence. - /// Buffer enabling each enumerator to retrieve elements from the shared source sequence. - /// is - /// - /// - /// + /// + /// Source sequence element type. + /// + /// + /// Source sequence. + /// + /// + /// is + /// + /// + /// Buffer enabling each enumerator to retrieve elements from the shared source sequence. + /// + /// + /// + /// This operator uses deferred execution and streams its result. + /// + /// public static IBuffer Share(this IEnumerable source) { Guard.IsNotNull(source); From 05c27f5d0e71bfe63667e6bb19a1cc70697fd4c6 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 13 Nov 2023 13:53:56 -0600 Subject: [PATCH 085/124] Update documentation for `Shuffle` --- .../SuperLinq.SuperEnumerable.Shuffle.md | 13 +++++ .../apidoc/SuperLinq/Shuffle/Shuffle1.linq | 17 ++++++ .../apidoc/SuperLinq/Shuffle/Shuffle2.linq | 17 ++++++ Source/SuperLinq/Shuffle.cs | 52 +++++++++++-------- 4 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Shuffle.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Shuffle/Shuffle1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Shuffle/Shuffle2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Shuffle.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Shuffle.md new file mode 100644 index 00000000..0a35ef88 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Shuffle.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.Shuffle``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to shuffle a sequence using `Shuffle`. +[!code-csharp[](SuperLinq/Shuffle/Shuffle1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Shuffle``1(System.Collections.Generic.IEnumerable{``0},System.Random) +example: [*content] +--- +The following code example demonstrates how to shuffle a sequence using `Shuffle`. +[!code-csharp[](SuperLinq/Shuffle/Shuffle2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Shuffle/Shuffle1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Shuffle/Shuffle1.linq new file mode 100644 index 00000000..66744437 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Shuffle/Shuffle1.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Shuffle a sequence +var result = sequence.Shuffle(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [10, 9, 3, 8, 1, 6, 2, 4, 7, 5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Shuffle/Shuffle2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Shuffle/Shuffle2.linq new file mode 100644 index 00000000..731ce377 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Shuffle/Shuffle2.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Shuffle a sequence +var result = sequence.Shuffle(new Random(10)); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 4, 2, 6, 3, 9, 5, 7, 10, 8] diff --git a/Source/SuperLinq/Shuffle.cs b/Source/SuperLinq/Shuffle.cs index 6de0b362..15559585 100644 --- a/Source/SuperLinq/Shuffle.cs +++ b/Source/SuperLinq/Shuffle.cs @@ -3,47 +3,55 @@ public static partial class SuperEnumerable { /// - /// Returns a sequence of elements in random order from the original - /// sequence. + /// Returns a sequence of elements in random order from the original sequence. /// - /// The type of source sequence elements. + /// The type of source sequence elements. + /// /// - /// The sequence from which to return random elements. + /// The sequence from which to return random elements. + /// + /// + /// is + /// /// - /// A sequence of elements randomized in - /// their order. + /// A sequence of elements randomized in their order. /// /// - /// This method uses deferred execution and streams its results. The - /// source sequence is entirely buffered before the results are - /// streamed. + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// /// - public static IEnumerable Shuffle(this IEnumerable source) { return Shuffle(source, new Random()); } /// - /// Returns a sequence of elements in random order from the original - /// sequence. An additional parameter specifies a random generator to be - /// used for the random selection algorithm. + /// Returns a sequence of elements in random order from the original sequence. An additional parameter specifies + /// a random generator to be used for the random selection algorithm. /// - /// The type of source sequence elements. + /// + /// The type of source sequence elements. + /// /// - /// The sequence from which to return random elements. + /// The sequence from which to return random elements. + /// /// - /// A random generator used as part of the selection algorithm. + /// A random generator used as part of the selection algorithm. + /// + /// + /// or is + /// /// - /// A sequence of elements randomized in - /// their order. + /// A sequence of elements randomized in their order. /// /// - /// This method uses deferred execution and streams its results. The - /// source sequence is entirely buffered before the results are - /// streamed. + /// + /// This method is implemented by using deferred execution. However, will be consumed + /// in it's entirety immediately when first element of the returned sequence is consumed. + /// /// - public static IEnumerable Shuffle(this IEnumerable source, Random rand) { Guard.IsNotNull(source); From e00df95d441b94c5255e921f4e820314138ba2af Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 13 Nov 2023 16:39:44 -0600 Subject: [PATCH 086/124] Update documentation for `SkipUntil` --- .../SuperLinq.SuperEnumerable.SkipUntil.md | 6 +++ .../apidoc/SuperLinq/SkipUntil/SkipUntil.linq | 18 ++++++++ Source/SuperLinq/SkipUntil.cs | 46 +++++++++++-------- 3 files changed, 50 insertions(+), 20 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SkipUntil.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/SkipUntil/SkipUntil.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SkipUntil.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SkipUntil.md new file mode 100644 index 00000000..a9c90d0c --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SkipUntil.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.SkipUntil``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to bypass elements in a sequence until a condition is true using `SkipUntil`. +[!code-csharp[](SuperLinq/SkipUntil/SkipUntil.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/SkipUntil/SkipUntil.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SkipUntil/SkipUntil.linq new file mode 100644 index 00000000..04b10653 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SkipUntil/SkipUntil.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Skip elements until the condition is true +var result = sequence + .SkipUntil(x => x == 5); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [6, 7, 8, 9, 10] diff --git a/Source/SuperLinq/SkipUntil.cs b/Source/SuperLinq/SkipUntil.cs index d205ab0e..45e2cfe5 100644 --- a/Source/SuperLinq/SkipUntil.cs +++ b/Source/SuperLinq/SkipUntil.cs @@ -3,35 +3,41 @@ public static partial class SuperEnumerable { /// - /// Skips items from the input sequence until the given predicate returns true - /// when applied to the current source item; that item will be the last skipped. + /// Skips items from the input sequence until the given predicate returns true when applied to the current + /// source item; that item will be the last skipped. /// + /// + /// Type of the source sequence + /// + /// + /// Source sequence + /// + /// + /// Predicate used to determine when to stop yielding results from the source. + /// + /// + /// or is + /// + /// + /// Items from the source sequence after the predicate first returns true when applied to the item. + /// /// /// - /// SkipUntil differs from Enumerable.SkipWhile in two respects. Firstly, the sense - /// of the predicate is reversed: it is expected that the predicate will return false - /// to start with, and then return true - for example, when trying to find a matching - /// item in a sequence. + /// SkipUntil differs from in two respects. /// /// - /// Secondly, SkipUntil skips the element which causes the predicate to return true. For - /// example, in a sequence and with a predicate of - /// x == 3]]>, the result would be . + /// Firstly, the sense of the predicate is reversed: it is expected that the predicate will return to start with, and then return - for example, when trying to find + /// a matching item in a sequence. /// /// - /// SkipUntil is as lazy as possible: it will not iterate over the source sequence - /// until it has to, it won't iterate further than it has to, and it won't evaluate - /// the predicate until it has to. (This means that an item may be returned which would - /// actually cause the predicate to throw an exception if it were evaluated, so long as - /// it comes after the first item causing the predicate to return true.) + /// Secondly, SkipUntil skips the element which causes the predicate to return . /// + /// + /// This operator uses deferred execution and streams its result. + /// /// - /// Type of the source sequence - /// Source sequence - /// Predicate used to determine when to stop yielding results from the source. - /// Items from the source sequence after the predicate first returns true when applied to the item. - /// or is null - public static IEnumerable SkipUntil(this IEnumerable source, Func predicate) { Guard.IsNotNull(source); From e1a72eb0943ea2aaa1ab7e07fa81f9f9d7cad3d2 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Mon, 13 Nov 2023 18:10:52 -0600 Subject: [PATCH 087/124] Update documentation for `SortedMerge(By)` --- .../SuperLinq.SuperEnumerable.SortedMerge.md | 27 ++ ...SuperLinq.SuperEnumerable.SortedMergeBy.md | 27 ++ .../SuperLinq/SortedMerge/SortedMerge1.linq | 20 + .../SuperLinq/SortedMerge/SortedMerge2.linq | 20 + .../SuperLinq/SortedMerge/SortedMerge3.linq | 20 + .../SuperLinq/SortedMerge/SortedMerge4.linq | 23 ++ .../SortedMergeBy/SortedMergeBy1.linq | 20 + .../SortedMergeBy/SortedMergeBy2.linq | 20 + .../SortedMergeBy/SortedMergeBy3.linq | 20 + .../SortedMergeBy/SortedMergeBy4.linq | 24 ++ Source/SuperLinq/SortedMerge.cs | 388 +++++++++++------- 11 files changed, 457 insertions(+), 152 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SortedMerge.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SortedMergeBy.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SortedMerge.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SortedMerge.md new file mode 100644 index 00000000..b1360489 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SortedMerge.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.SortedMerge``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0}[]) +example: [*content] +--- +The following code example demonstrates how to merge two or more sequences that are in a common order into a single sequence that preserves that order using `SortedMerge`. +[!code-csharp[](SuperLinq/SortedMerge/SortedMerge1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.SortedMerge``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IComparer{``0},System.Collections.Generic.IEnumerable{``0}[]) +example: [*content] +--- +The following code example demonstrates how to merge two or more sequences that are in a common order into a single sequence that preserves that order using `SortedMerge`. +[!code-csharp[](SuperLinq/SortedMerge/SortedMerge2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.SortedMerge``1(System.Collections.Generic.IEnumerable{``0},SuperLinq.OrderByDirection,System.Collections.Generic.IEnumerable{``0}[]) +example: [*content] +--- +The following code example demonstrates how to merge two or more sequences that are in a common order into a single sequence that preserves that order using `SortedMerge`. +[!code-csharp[](SuperLinq/SortedMerge/SortedMerge3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.SortedMerge``1(System.Collections.Generic.IEnumerable{``0},SuperLinq.OrderByDirection,System.Collections.Generic.IComparer{``0},System.Collections.Generic.IEnumerable{``0}[]) +example: [*content] +--- +The following code example demonstrates how to merge two or more sequences that are in a common order into a single sequence that preserves that order using `SortedMerge`. +[!code-csharp[](SuperLinq/SortedMerge/SortedMerge4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SortedMergeBy.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SortedMergeBy.md new file mode 100644 index 00000000..d14126b4 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.SortedMergeBy.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.SortedMergeBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IEnumerable{``0}[]) +example: [*content] +--- +The following code example demonstrates how to merge two or more sequences that are in a common order into a single sequence that preserves that order using `SortedMergeBy`. +[!code-csharp[](SuperLinq/SortedMergeBy/SortedMergeBy1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.SortedMergeBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IComparer{``1},System.Collections.Generic.IEnumerable{``0}[]) +example: [*content] +--- +The following code example demonstrates how to merge two or more sequences that are in a common order into a single sequence that preserves that order using `SortedMergeBy`. +[!code-csharp[](SuperLinq/SortedMergeBy/SortedMergeBy2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.SortedMergeBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},SuperLinq.OrderByDirection,System.Collections.Generic.IEnumerable{``0}[]) +example: [*content] +--- +The following code example demonstrates how to merge two or more sequences that are in a common order into a single sequence that preserves that order using `SortedMergeBy`. +[!code-csharp[](SuperLinq/SortedMergeBy/SortedMergeBy3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.SortedMergeBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},SuperLinq.OrderByDirection,System.Collections.Generic.IComparer{``1},System.Collections.Generic.IEnumerable{``0}[]) +example: [*content] +--- +The following code example demonstrates how to merge two or more sequences that are in a common order into a single sequence that preserves that order using `SortedMergeBy`. +[!code-csharp[](SuperLinq/SortedMergeBy/SortedMergeBy4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge1.linq new file mode 100644 index 00000000..b7f8ab89 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge1.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var s1 = new[] { 3, 7, 11 }; +var s2 = new[] { 2, 4, 20 }; +var s3 = new[] { 17, 19, 25 }; + +// Execute a sorted merge of multiple sequences into a single sequence +var result = s1 + .SortedMerge(s2, s3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [2, 3, 4, 7, 11, 17, 19, 20, 25] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge2.linq new file mode 100644 index 00000000..0b7a3251 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge2.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var s1 = new[] { 3, 7, 11 }; +var s2 = new[] { 2, 4, 20 }; +var s3 = new[] { 17, 19, 25 }; + +// Execute a sorted merge of multiple sequences into a single sequence +var result = s1 + .SortedMerge(Comparer.Default, s2, s3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [2, 3, 4, 7, 11, 17, 19, 20, 25] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge3.linq new file mode 100644 index 00000000..5963286d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge3.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var s1 = new[] { 11, 7, 3 }; +var s2 = new[] { 20, 4, 2 }; +var s3 = new[] { 25, 19, 17 }; + +// Execute a sorted merge of multiple sequences into a single sequence +var result = s1 + .SortedMerge(OrderByDirection.Descending, s2, s3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [25, 20, 19, 17, 11, 7, 4, 3, 2] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge4.linq new file mode 100644 index 00000000..bb7d52fd --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMerge/SortedMerge4.linq @@ -0,0 +1,23 @@ + + SuperLinq + SuperLinq + + +var s1 = new[] { 11, 7, 3 }; +var s2 = new[] { 20, 4, 2 }; +var s3 = new[] { 25, 19, 17 }; + +// Execute a sorted merge of multiple sequences into a single sequence +var result = s1 + .SortedMerge( + OrderByDirection.Descending, + Comparer.Default, + s2, s3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [25, 20, 19, 17, 11, 7, 4, 3, 2] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy1.linq new file mode 100644 index 00000000..3521f9ef --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy1.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var s1 = new[] { 11, 7, 3 }; +var s2 = new[] { 20, 4, 2 }; +var s3 = new[] { 25, 19, 17 }; + +// Execute a sorted merge of multiple sequences into a single sequence +var result = s1 + .SortedMergeBy(x => -x, s2, s3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [25, 20, 19, 17, 11, 7, 4, 3, 2] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy2.linq new file mode 100644 index 00000000..fb8913cb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy2.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var s1 = new[] { 11, 7, 3 }; +var s2 = new[] { 20, 4, 2 }; +var s3 = new[] { 25, 19, 17 }; + +// Execute a sorted merge of multiple sequences into a single sequence +var result = s1 + .SortedMergeBy(x => -x, Comparer.Default, s2, s3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [25, 20, 19, 17, 11, 7, 4, 3, 2] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy3.linq new file mode 100644 index 00000000..54638686 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy3.linq @@ -0,0 +1,20 @@ + + SuperLinq + SuperLinq + + +var s1 = new[] { 3, 7, 11 }; +var s2 = new[] { 2, 4, 20 }; +var s3 = new[] { 17, 19, 25 }; + +// Execute a sorted merge of multiple sequences into a single sequence +var result = s1 + .SortedMergeBy(x => -x, OrderByDirection.Descending, s2, s3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [2, 3, 4, 7, 11, 17, 19, 20, 25] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy4.linq new file mode 100644 index 00000000..9ae6f098 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/SortedMergeBy/SortedMergeBy4.linq @@ -0,0 +1,24 @@ + + SuperLinq + SuperLinq + + +var s1 = new[] { 3, 7, 11 }; +var s2 = new[] { 2, 4, 20 }; +var s3 = new[] { 17, 19, 25 }; + +// Execute a sorted merge of multiple sequences into a single sequence +var result = s1 + .SortedMergeBy( + x => -x, + OrderByDirection.Descending, + Comparer.Default, + s2, s3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [2, 3, 4, 7, 11, 17, 19, 20, 25] diff --git a/Source/SuperLinq/SortedMerge.cs b/Source/SuperLinq/SortedMerge.cs index a96b60fc..32d3f064 100644 --- a/Source/SuperLinq/SortedMerge.cs +++ b/Source/SuperLinq/SortedMerge.cs @@ -3,31 +3,31 @@ public static partial class SuperEnumerable { /// - /// Merges two or more sequences that are in a common order (either ascending or descending) into - /// a single sequence that preserves that order. + /// Merges two or more sequences that are in a common order into a single sequence that preserves that order. /// + /// + /// The type of the elements of the sequence + /// + /// + /// The primary sequence with which to merge + /// + /// + /// A variable argument array of zero or more other sequences to merge with + /// + /// + /// or is . + /// + /// + /// A merged, order-preserving sequence containing all of the elements of the original sequences + /// /// - /// Using SortedMerge on sequences that are not ordered or are not in the same order produces - /// undefined results.
- /// This method uses deferred execution and streams its results.
- /// - /// Here is an example of a merge, as well as the produced result: - /// + /// + /// Using SortedMerge on sequences that are not ordered or are not in the same order produces undefined results. + /// + /// + /// This method uses deferred execution and streams its results. + /// ///
- /// The type of the elements of the sequence - /// The primary sequence with which to merge - /// A variable argument array of zero or more other sequences to merge with - /// A merged, order-preserving sequence containing all of the elements of the original sequences - /// is . - /// is . public static IEnumerable SortedMerge(this IEnumerable source, params IEnumerable[] otherSequences) { return SortedMerge(source, OrderByDirection.Ascending, comparer: null, otherSequences); @@ -65,32 +65,34 @@ public static IEnumerable SortedMergeDescending(this IEnumerab } /// - /// Merges two or more sequences that are in a common order (either ascending or descending) into - /// a single sequence that preserves that order. + /// Merges two or more sequences that are in a common order into a single sequence that preserves that order. /// + /// + /// The type of the elements of the sequence + /// + /// + /// The primary sequence with which to merge + /// + /// + /// A variable argument array of zero or more other sequences to merge with + /// + /// + /// An to compare elements + /// + /// + /// or is . + /// + /// + /// A merged, order-preserving sequence containing all of the elements of the original sequences + /// /// - /// Using SortedMerge on sequences that are not ordered or are not in the same order produces - /// undefined results.
- /// This method uses deferred execution and streams its results.
- /// - /// Here is an example of a merge, as well as the produced result: - /// + /// + /// Using SortedMerge on sequences that are not ordered or are not in the same order produces undefined results. + /// + /// + /// This method uses deferred execution and streams its results. + /// ///
- /// The type of the elements of the sequence - /// The primary sequence with which to merge - /// The comparer used to evaluate the relative order between elements - /// A variable argument array of zero or more other sequences to merge with - /// A merged, order-preserving sequence containing all of the elements of the original sequences - /// is . - /// is . public static IEnumerable SortedMerge(this IEnumerable source, IComparer? comparer, params IEnumerable[] otherSequences) { return SortedMerge(source, OrderByDirection.Ascending, comparer, otherSequences); @@ -129,88 +131,111 @@ public static IEnumerable SortedMergeDescending(this IEnumerab } /// - /// Merges two or more sequences that are in a common order (either ascending or descending) into - /// a single sequence that preserves that order. + /// Merges two or more sequences that are in a common order (either ascending or descending) into a single sequence that preserves that order. /// + /// + /// The type of the elements of the sequence + /// + /// + /// The primary sequence with which to merge + /// + /// + /// A variable argument array of zero or more other sequences to merge with + /// + /// + /// A direction in which to order the elements (ascending, descending) + /// + /// + /// or is . + /// + /// + /// A merged, order-preserving sequence containing all of the elements of the original sequences + /// /// - /// Using SortedMerge on sequences that are not ordered or are not in the same order produces - /// undefined results.
- /// This method uses deferred execution and streams its results.
- /// - /// Here is an example of a merge, as well as the produced result: - /// + /// + /// Using SortedMerge on sequences that are not ordered or are not in the same order produces undefined results. + /// + /// + /// This method uses deferred execution and streams its results. + /// ///
- /// The type of the elements of the sequence - /// The primary sequence with which to merge - /// The ordering that all sequences must already exhibit - /// A variable argument array of zero or more other sequences to merge with - /// A merged, order-preserving sequence containing all of the elements of the original sequences - /// is . - /// is . public static IEnumerable SortedMerge(this IEnumerable source, OrderByDirection direction, params IEnumerable[] otherSequences) { return SortedMerge(source, direction, comparer: null, otherSequences); } /// - /// Merges two or more sequences that are in a common order (either ascending or descending) into - /// a single sequence that preserves that order. + /// Merges two or more sequences that are in a common order (either ascending or descending) into a single sequence that preserves that order. /// + /// + /// The type of the elements of the sequence + /// + /// + /// The primary sequence with which to merge + /// + /// + /// A variable argument array of zero or more other sequences to merge with + /// + /// + /// A direction in which to order the elements (ascending, descending) + /// + /// + /// An to compare elements + /// + /// + /// or is . + /// + /// + /// A merged, order-preserving sequence containing all of the elements of the original sequences + /// /// - /// Using SortedMerge on sequences that are not ordered or are not in the same order produces - /// undefined results.
- /// This method uses deferred execution and streams its results.
- /// - /// Here is an example of a merge, as well as the produced result: - /// + /// + /// Using SortedMerge on sequences that are not ordered or are not in the same order produces undefined results. + /// + /// + /// This method uses deferred execution and streams its results. + /// ///
- /// The type of the elements in the sequence - /// The primary sequence with which to merge - /// The ordering that all sequences must already exhibit - /// The comparer used to evaluate the relative order between elements - /// A variable argument array of zero or more other sequences to merge with - /// A merged, order-preserving sequence containing all of the elements of the original sequences - /// is . - /// is . public static IEnumerable SortedMerge(this IEnumerable source, OrderByDirection direction, IComparer? comparer, params IEnumerable[] otherSequences) { return SortedMergeBy(source, Identity, direction, comparer, otherSequences); } /// - /// Merges two or more sequences that are in a common order (either ascending or descending) - /// according to a key into a single sequence that preserves that order. + /// Merges two or more sequences that are in a common order according to a key into a single sequence that + /// preserves that order. /// + /// + /// The type of the elements of the sequence + /// + /// + /// The type of the key used to order elements + /// + /// + /// The primary sequence with which to merge + /// + /// + /// A key selector function + /// + /// + /// A variable argument array of zero or more other sequences to merge with + /// + /// + /// , or is . + /// + /// + /// A merged, order-preserving sequence containing all of the elements of the original sequences + /// /// - /// Using SortedMergeBy on sequences that are not ordered or are not in the same order produces - /// undefined results.
- /// This method uses deferred execution and streams its results.
+ /// + /// Using SortedMergeBy on sequences that are not ordered or are not in the same order produces undefined + /// results. + /// + /// + /// This method uses deferred execution and streams its results. + /// ///
- /// The type of the elements of the sequence - /// The type of the key returned by - /// The primary sequence with which to merge - /// A function to extract a key from an element. - /// A variable argument array of zero or more other sequences to merge with - /// A merged, order-preserving sequence containing all of the elements of the original sequences - /// is . - /// is . - /// is . public static IEnumerable SortedMergeBy(this IEnumerable source, Func keySelector, params IEnumerable[] otherSequences) { return SortedMergeBy(source, keySelector, OrderByDirection.Ascending, comparer: null, otherSequences); @@ -240,24 +265,43 @@ public static IEnumerable SortedMergeByDescending(this I } /// - /// Merges two or more sequences that are in a common order (either ascending or descending) - /// according to a key into a single sequence that preserves that order. + /// Merges two or more sequences that are in a common order according to a key into a single sequence that + /// preserves that order. /// + /// + /// The type of the elements of the sequence + /// + /// + /// The type of the key used to order elements + /// + /// + /// The primary sequence with which to merge + /// + /// + /// A key selector function + /// + /// + /// A variable argument array of zero or more other sequences to merge with + /// + /// + /// An to compare keys + /// + /// + /// , or is . + /// + /// + /// A merged, order-preserving sequence containing all of the elements of the original sequences + /// /// - /// Using SortedMergeBy on sequences that are not ordered or are not in the same order produces - /// undefined results.
- /// This method uses deferred execution and streams its results.
+ /// + /// Using SortedMergeBy on sequences that are not ordered or are not in the same order produces undefined + /// results. + /// + /// + /// This method uses deferred execution and streams its results. + /// ///
- /// The type of the elements of the sequence - /// The type of the key returned by - /// The primary sequence with which to merge - /// A function to extract a key from an element. - /// The comparer used to evaluate the relative order between elements - /// A variable argument array of zero or more other sequences to merge with - /// A merged, order-preserving sequence containing all of the elements of the original sequences - /// is . - /// is . - /// is . public static IEnumerable SortedMergeBy(this IEnumerable source, Func keySelector, IComparer? comparer, params IEnumerable[] otherSequences) { return SortedMergeBy(source, keySelector, OrderByDirection.Ascending, comparer, otherSequences); @@ -288,49 +332,89 @@ public static IEnumerable SortedMergeByDescending(this I } /// - /// Merges two or more sequences that are in a common order (either ascending or descending) - /// according to a key into a single sequence that preserves that order. + /// Merges two or more sequences that are in a common order (either ascending or descending) according to a key + /// into a single sequence that preserves that order. /// + /// + /// The type of the elements of the sequence + /// + /// + /// The type of the key used to order elements + /// + /// + /// The primary sequence with which to merge + /// + /// + /// A key selector function + /// + /// + /// A variable argument array of zero or more other sequences to merge with + /// + /// + /// A direction in which to order the elements (ascending, descending) + /// + /// + /// , or is . + /// + /// + /// A merged, order-preserving sequence containing all of the elements of the original sequences + /// /// - /// Using SortedMergeBy on sequences that are not ordered or are not in the same order produces - /// undefined results.
- /// This method uses deferred execution and streams its results.
+ /// + /// Using SortedMergeBy on sequences that are not ordered or are not in the same order produces undefined + /// results. + /// + /// + /// This method uses deferred execution and streams its results. + /// ///
- /// The type of the elements of the sequence - /// The type of the key returned by - /// The primary sequence with which to merge - /// A function to extract a key from an element. - /// The ordering that all sequences must already exhibit - /// A variable argument array of zero or more other sequences to merge with - /// A merged, order-preserving sequence containing all of the elements of the original sequences - /// is . - /// is . - /// is . public static IEnumerable SortedMergeBy(this IEnumerable source, Func keySelector, OrderByDirection direction, params IEnumerable[] otherSequences) { return SortedMergeBy(source, keySelector, direction, comparer: null, otherSequences); } /// - /// Merges two or more sequences that are in a common order (either ascending or descending) - /// according to a key into a single sequence that preserves that order. + /// Merges two or more sequences that are in a common order (either ascending or descending) according to a key + /// into a single sequence that preserves that order. /// + /// + /// The type of the elements of the sequence + /// + /// + /// The type of the key used to order elements + /// + /// + /// The primary sequence with which to merge + /// + /// + /// A key selector function + /// + /// + /// A variable argument array of zero or more other sequences to merge with + /// + /// + /// A direction in which to order the elements (ascending, descending) + /// + /// + /// An to compare keys + /// + /// + /// , or is . + /// + /// + /// A merged, order-preserving sequence containing all of the elements of the original sequences + /// /// - /// Using SortedMergeBy on sequences that are not ordered or are not in the same order produces - /// undefined results.
- /// This method uses deferred execution and streams its results.
+ /// + /// Using SortedMergeBy on sequences that are not ordered or are not in the same order produces undefined + /// results. + /// + /// + /// This method uses deferred execution and streams its results. + /// ///
- /// The type of the elements in the sequence - /// The type of the key returned by - /// The primary sequence with which to merge - /// A function to extract a key from an element. - /// The ordering that all sequences must already exhibit - /// The comparer used to evaluate the relative order between elements - /// A variable argument array of zero or more other sequences to merge with - /// A merged, order-preserving sequence containing all of the elements of the original sequences - /// is . - /// is . - /// is . public static IEnumerable SortedMergeBy(this IEnumerable source, Func keySelector, OrderByDirection direction, IComparer? comparer, params IEnumerable[] otherSequences) { Guard.IsNotNull(source); From a5dc17d273cdd29758cf33f57f177e1b22a758c2 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 14 Nov 2023 07:31:05 -0600 Subject: [PATCH 088/124] Update documentation for `Split` --- .../apidoc/SuperLinq.SuperEnumerable.Split.md | 83 +++ .../apidoc/SuperLinq/Split/Split1.linq | 23 + .../apidoc/SuperLinq/Split/Split10.linq | 24 + .../apidoc/SuperLinq/Split/Split11.linq | 18 + .../apidoc/SuperLinq/Split/Split12.linq | 18 + .../apidoc/SuperLinq/Split/Split2.linq | 23 + .../apidoc/SuperLinq/Split/Split3.linq | 26 + .../apidoc/SuperLinq/Split/Split4.linq | 26 + .../apidoc/SuperLinq/Split/Split5.linq | 18 + .../apidoc/SuperLinq/Split/Split6.linq | 18 + .../apidoc/SuperLinq/Split/Split7.linq | 18 + .../apidoc/SuperLinq/Split/Split8.linq | 18 + .../apidoc/SuperLinq/Split/Split9.linq | 25 + Source/SuperLinq/Split.cs | 494 +++++++++++++----- 14 files changed, 694 insertions(+), 138 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Split.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split10.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split11.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split12.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split5.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split6.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split7.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split8.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split9.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Split.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Split.md new file mode 100644 index 00000000..870257b9 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Split.md @@ -0,0 +1,83 @@ +--- +uid: SuperLinq.SuperEnumerable.Split``1(System.Collections.Generic.IEnumerable{``0},``0) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a value using `Split`. +[!code-csharp[](SuperLinq/Split/Split1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Split``1(System.Collections.Generic.IEnumerable{``0},``0,System.Collections.Generic.IEqualityComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a value using `Split`. +[!code-csharp[](SuperLinq/Split/Split2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Split``1(System.Collections.Generic.IEnumerable{``0},``0,System.Int32) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a value using `Split`. +[!code-csharp[](SuperLinq/Split/Split3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Split``1(System.Collections.Generic.IEnumerable{``0},``0,System.Collections.Generic.IEqualityComparer{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a value using `Split`. +[!code-csharp[](SuperLinq/Split/Split4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Split``2(System.Collections.Generic.IEnumerable{``0},``0,System.Func{System.Collections.Generic.IEnumerable{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a value using `Split`. +[!code-csharp[](SuperLinq/Split/Split5.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Split``2(System.Collections.Generic.IEnumerable{``0},``0,System.Collections.Generic.IEqualityComparer{``0},System.Func{System.Collections.Generic.IEnumerable{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a value using `Split`. +[!code-csharp[](SuperLinq/Split/Split6.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Split``2(System.Collections.Generic.IEnumerable{``0},``0,System.Int32,System.Func{System.Collections.Generic.IEnumerable{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a value using `Split`. +[!code-csharp[](SuperLinq/Split/Split7.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Split``2(System.Collections.Generic.IEnumerable{``0},``0,System.Collections.Generic.IEqualityComparer{``0},System.Int32,System.Func{System.Collections.Generic.IEnumerable{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a value using `Split`. +[!code-csharp[](SuperLinq/Split/Split8.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Split``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a condition using `Split`. +[!code-csharp[](SuperLinq/Split/Split9.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Split``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean},System.Int32) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a condition using `Split`. +[!code-csharp[](SuperLinq/Split/Split10.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Split``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean},System.Func{System.Collections.Generic.IEnumerable{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a condition using `Split`. +[!code-csharp[](SuperLinq/Split/Split11.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Split``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean},System.Int32,System.Func{System.Collections.Generic.IEnumerable{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to split a sequence based on a condition using `Split`. +[!code-csharp[](SuperLinq/Split/Split12.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split1.linq new file mode 100644 index 00000000..7e9c1333 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split1.linq @@ -0,0 +1,23 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 11); + +// split a sequence using a key value +var result = sequence + .Split(5); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [0, 1, 2, 3, 4], +// [6, 7, 8, 9, 10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split10.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split10.linq new file mode 100644 index 00000000..0505710d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split10.linq @@ -0,0 +1,24 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 11); + +// split a sequence using a key value +var result = sequence + .Split(x => x % 3 == 2, 2); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [0, 1], +// [3, 4], +// [6, 7, 8, 9, 10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split11.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split11.linq new file mode 100644 index 00000000..f3bdf263 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split11.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 11); + +// split a sequence using a key value +var result = sequence + .Split(x => x % 3 == 2, g => g.Sum()); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 7, 13, 19] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split12.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split12.linq new file mode 100644 index 00000000..cb6b0762 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split12.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 11); + +// split a sequence using a key value +var result = sequence + .Split(x => x % 3 == 2, 2, g => g.Sum()); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 7, 40] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split2.linq new file mode 100644 index 00000000..5e14b21f --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split2.linq @@ -0,0 +1,23 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 11); + +// split a sequence using a key value +var result = sequence + .Split(5, EqualityComparer.Default); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [0, 1, 2, 3, 4], +// [6, 7, 8, 9, 10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split3.linq new file mode 100644 index 00000000..d92dc1cd --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split3.linq @@ -0,0 +1,26 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 3).Repeat(10); + +// split a sequence using a key value +var result = sequence + .Split(2, 4); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [0, 1], +// [0, 1], +// [0, 1], +// [0, 1], +// [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split4.linq new file mode 100644 index 00000000..c6ceaff8 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split4.linq @@ -0,0 +1,26 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 3).Repeat(10); + +// split a sequence using a key value +var result = sequence + .Split(2, EqualityComparer.Default, 4); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [0, 1], +// [0, 1], +// [0, 1], +// [0, 1], +// [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split5.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split5.linq new file mode 100644 index 00000000..ba76bd75 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split5.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 11); + +// split a sequence using a key value +var result = sequence + .Split(5, g => g.Sum()); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [10, 40] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split6.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split6.linq new file mode 100644 index 00000000..c6c2ee60 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split6.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 11); + +// split a sequence using a key value +var result = sequence + .Split(5, EqualityComparer.Default, g => g.Sum()); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [10, 40] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split7.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split7.linq new file mode 100644 index 00000000..91bd17d1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split7.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 3).Repeat(10); + +// split a sequence using a key value +var result = sequence + .Split(2, 4, g => g.Sum()); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 1, 1, 1, 18] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split8.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split8.linq new file mode 100644 index 00000000..cfa0c180 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split8.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 3).Repeat(10); + +// split a sequence using a key value +var result = sequence + .Split(2, EqualityComparer.Default, 4, g => g.Sum()); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 1, 1, 1, 18] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split9.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split9.linq new file mode 100644 index 00000000..c4ba0bc5 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Split/Split9.linq @@ -0,0 +1,25 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 11); + +// split a sequence using a key value +var result = sequence + .Split(x => x % 3 == 2); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [0, 1], +// [3, 4], +// [6, 7], +// [9, 10] +// ] diff --git a/Source/SuperLinq/Split.cs b/Source/SuperLinq/Split.cs index be1d454c..e90ba283 100644 --- a/Source/SuperLinq/Split.cs +++ b/Source/SuperLinq/Split.cs @@ -4,13 +4,30 @@ public static partial class SuperEnumerable { /// - /// Splits the source sequence by a separator. + /// Splits the source sequence by a separator. /// - /// Type of element in the source sequence. - /// The source sequence. - /// Separator element. - /// A sequence of splits of elements. - /// is . + /// + /// Type of element in the source sequence. + /// + /// + /// The source sequence. + /// + /// + /// Separator element. + /// + /// + /// is . + /// + /// + /// A sequence of splits of elements. + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable> Split( this IEnumerable source, TSource separator) @@ -19,15 +36,36 @@ public static IEnumerable> Split( } /// - /// Splits the source sequence by a separator given a maximum count of splits. + /// Splits the source sequence by a separator given a maximum count of splits. /// - /// Type of element in the source sequence. - /// The source sequence. - /// Separator element. - /// Maximum number of splits. - /// A sequence of splits of elements. - /// is . - /// is less than 1. + /// + /// Type of element in the source sequence. + /// + /// + /// The source sequence. + /// + /// + /// Separator element. + /// + /// + /// Maximum number of splits. + /// + /// + /// is . + /// + /// + /// is less than 1. + /// + /// + /// A sequence of splits of elements. + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable> Split( this IEnumerable source, TSource separator, int count) @@ -36,20 +74,36 @@ public static IEnumerable> Split( } /// - /// Splits the source sequence by a separator and then transforms - /// the splits into results. + /// Splits the source sequence by a separator and then transforms the splits into results. /// - /// Type of element in the source sequence. - /// Type of the result sequence elements. - /// The source sequence. - /// Separator element. - /// Function used to project splits - /// of source elements into elements of the resulting sequence. + /// + /// Type of element in the source sequence. + /// + /// + /// Type of the result sequence elements. + /// + /// + /// The source sequence. + /// + /// + /// Separator element. + /// + /// + /// Function used to project splits of source elements into elements of the resulting sequence. + /// /// - /// A sequence of values typed as . + /// A sequence of values typed as . /// - /// is . - /// is . + /// + /// or is . + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable Split( this IEnumerable source, TSource separator, @@ -59,22 +113,43 @@ public static IEnumerable Split( } /// - /// Splits the source sequence by a separator, given a maximum count - /// of splits, and then transforms the splits into results. + /// Splits the source sequence by a separator, given a maximum count of splits, and then transforms the splits + /// into results. /// - /// Type of element in the source sequence. - /// Type of the result sequence elements. - /// The source sequence. - /// Separator element. - /// Maximum number of splits. - /// Function used to project splits - /// of source elements into elements of the resulting sequence. + /// + /// Type of element in the source sequence. + /// + /// + /// Type of the result sequence elements. + /// + /// + /// The source sequence. + /// + /// + /// Separator element. + /// + /// + /// Maximum number of splits. + /// + /// + /// Function used to project splits of source elements into elements of the resulting sequence. + /// /// - /// A sequence of values typed as . + /// A sequence of values typed as . /// - /// is . - /// is . - /// is less than 1. + /// + /// or is . + /// + /// + /// is less than 1. + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable Split( this IEnumerable source, TSource separator, int count, @@ -84,16 +159,33 @@ public static IEnumerable Split( } /// - /// Splits the source sequence by a separator and then transforms the - /// splits into results. + /// Splits the source sequence by a separator and then transforms the splits into results. /// - /// Type of element in the source sequence. - /// The source sequence. - /// Separator element. - /// Comparer used to determine separator - /// element equality. - /// A sequence of splits of elements. - /// is . + /// + /// Type of element in the source sequence. + /// + /// + /// The source sequence. + /// + /// + /// Separator element. + /// + /// + /// Comparer used to determine separator element equality. + /// + /// + /// A sequence of splits of elements. + /// + /// + /// is . + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable> Split( this IEnumerable source, TSource separator, IEqualityComparer? comparer) @@ -102,19 +194,40 @@ public static IEnumerable> Split( } /// - /// Splits the source sequence by a separator, given a maximum count - /// of splits. A parameter specifies how the separator is compared - /// for equality. + /// Splits the source sequence by a separator, given a maximum count of splits. A parameter specifies how the + /// separator is compared for equality. /// - /// Type of element in the source sequence. - /// The source sequence. - /// Separator element. - /// Comparer used to determine separator - /// element equality. - /// Maximum number of splits. - /// A sequence of splits of elements. - /// is . - /// is less than 1. + /// + /// Type of element in the source sequence. + /// + /// + /// The source sequence. + /// + /// + /// Separator element. + /// + /// + /// Comparer used to determine separator element equality. + /// + /// + /// Maximum number of splits. + /// + /// + /// A sequence of splits of elements. + /// + /// + /// is . + /// + /// + /// is less than 1. + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable> Split( this IEnumerable source, TSource separator, IEqualityComparer? comparer, int count) @@ -123,23 +236,40 @@ public static IEnumerable> Split( } /// - /// Splits the source sequence by a separator and then transforms the - /// splits into results. A parameter specifies how the separator is - /// compared for equality. + /// Splits the source sequence by a separator and then transforms the splits into results. A parameter specifies + /// how the separator is compared for equality. /// - /// Type of element in the source sequence. - /// Type of the result sequence elements. - /// The source sequence. - /// Separator element. - /// Comparer used to determine separator - /// element equality. - /// Function used to project splits - /// of source elements into elements of the resulting sequence. + /// + /// Type of element in the source sequence. + /// + /// + /// Type of the result sequence elements. + /// + /// + /// The source sequence. + /// + /// + /// Separator element. + /// + /// + /// Comparer used to determine separator element equality. + /// + /// + /// Function used to project splits of source elements into elements of the resulting sequence. + /// /// - /// A sequence of values typed as . + /// A sequence of values typed as . /// - /// is . - /// is . + /// + /// or is . + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable Split( this IEnumerable source, TSource separator, IEqualityComparer comparer, @@ -149,25 +279,46 @@ public static IEnumerable Split( } /// - /// Splits the source sequence by a separator, given a maximum count - /// of splits, and then transforms the splits into results. A - /// parameter specifies how the separator is compared for equality. + /// Splits the source sequence by a separator, given a maximum count of splits, and then transforms the splits + /// into results. A parameter specifies how the separator is compared for equality. /// - /// Type of element in the source sequence. - /// Type of the result sequence elements. - /// The source sequence. - /// Separator element. - /// Comparer used to determine separator - /// element equality. - /// Maximum number of splits. - /// Function used to project splits - /// of source elements into elements of the resulting sequence. + /// + /// Type of element in the source sequence. + /// + /// + /// Type of the result sequence elements. + /// + /// + /// The source sequence. + /// + /// + /// Separator element. + /// + /// + /// Comparer used to determine separator element equality. + /// + /// + /// Maximum number of splits. + /// + /// + /// Function used to project splits of source elements into elements of the resulting sequence. + /// /// - /// A sequence of values typed as . + /// A sequence of values typed as . /// - /// is . - /// is . - /// is less than 1. + /// + /// or is . + /// + /// + /// is less than 1. + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable Split( this IEnumerable source, TSource separator, IEqualityComparer? comparer, int count, @@ -182,16 +333,30 @@ public static IEnumerable Split( } /// - /// Splits the source sequence by separator elements identified by a - /// function. + /// Splits the source sequence by separator elements identified by a function. /// - /// Type of element in the source sequence. - /// The source sequence. - /// Predicate function used to determine - /// the splitter elements in the source sequence. - /// A sequence of splits of elements. - /// is . - /// is . + /// + /// Type of element in the source sequence. + /// + /// + /// The source sequence. + /// + /// + /// Predicate function used to determine the splitter elements in the source sequence. + /// + /// + /// A sequence of splits of elements. + /// + /// + /// or is . + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable> Split( this IEnumerable source, Func separatorFunc) @@ -200,18 +365,36 @@ public static IEnumerable> Split( } /// - /// Splits the source sequence by separator elements identified by a - /// function, given a maximum count of splits. + /// Splits the source sequence by separator elements identified by a function, given a maximum count of splits. /// - /// Type of element in the source sequence. - /// The source sequence. - /// Predicate function used to determine - /// the splitter elements in the source sequence. - /// Maximum number of splits. - /// A sequence of splits of elements. - /// is . - /// is . - /// is less than 1. + /// + /// Type of element in the source sequence. + /// + /// + /// The source sequence. + /// + /// + /// Predicate function used to determine the splitter elements in the source sequence. + /// + /// + /// Maximum number of splits. + /// + /// + /// A sequence of splits of elements. + /// + /// + /// or is . + /// + /// + /// is less than 1. + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable> Split( this IEnumerable source, Func separatorFunc, int count) @@ -220,22 +403,38 @@ public static IEnumerable> Split( } /// - /// Splits the source sequence by separator elements identified by - /// a function and then transforms the splits into results. + /// Splits the source sequence by separator elements identified by a function and then transforms the splits + /// into results. /// - /// Type of element in the source sequence. - /// Type of the result sequence elements. - /// The source sequence. - /// Predicate function used to determine - /// the splitter elements in the source sequence. - /// Function used to project splits - /// of source elements into elements of the resulting sequence. + /// + /// Type of element in the source sequence. + /// + /// + /// Type of the result sequence elements. + /// + /// + /// The source sequence. + /// + /// + /// Predicate function used to determine the splitter elements in the source sequence. + /// + /// + /// Function used to project splits of source elements into elements of the resulting sequence. + /// /// - /// A sequence of values typed as . + /// A sequence of values typed as . /// - /// is . - /// is . - /// is . + /// + /// , , or is . + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable Split( this IEnumerable source, Func separatorFunc, @@ -245,25 +444,44 @@ public static IEnumerable Split( } /// - /// Splits the source sequence by separator elements identified by - /// a function, given a maximum count of splits, and then transforms - /// the splits into results. + /// Splits the source sequence by separator elements identified by a function, given a maximum count of splits, + /// and then transforms the splits into results. /// - /// Type of element in the source sequence. - /// Type of the result sequence elements. - /// The source sequence. - /// Predicate function used to determine - /// the splitter elements in the source sequence. - /// Maximum number of splits. - /// Function used to project a split - /// group of source elements into an element of the resulting sequence. + /// + /// Type of element in the source sequence. + /// + /// + /// Type of the result sequence elements. + /// + /// + /// The source sequence. + /// + /// + /// Predicate function used to determine the splitter elements in the source sequence. + /// + /// + /// Maximum number of splits. + /// + /// + /// Function used to project a split group of source elements into an element of the resulting sequence. + /// /// - /// A sequence of values typed as . + /// A sequence of values typed as . /// - /// is . - /// is . - /// is . - /// is less than 1. + /// + /// , , or is . + /// + /// + /// is less than 1. + /// + /// + /// + /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, + /// however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next + /// grouping occurs. + /// + /// public static IEnumerable Split( this IEnumerable source, Func separatorFunc, int count, From fcd677014ea45f784b8c371813b461372197e56a Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 14 Nov 2023 07:46:25 -0600 Subject: [PATCH 089/124] Update documentation for `StartsWith` --- .../SuperLinq.SuperEnumerable.StartsWith.md | 13 ++++ .../SuperLinq/StartsWith/StartsWith1.linq | 39 +++++++++++ .../SuperLinq/StartsWith/StartsWith2.linq | 39 +++++++++++ Source/SuperLinq/StartsWith.cs | 69 +++++++++++-------- 4 files changed, 132 insertions(+), 28 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.StartsWith.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/StartsWith/StartsWith1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/StartsWith/StartsWith2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.StartsWith.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.StartsWith.md new file mode 100644 index 00000000..84f6e4ee --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.StartsWith.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.StartsWith``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to check that one sequence starts with the same elements as another sequence using `StartsWith`. +[!code-csharp[](SuperLinq/StartsWith/StartsWith1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.StartsWith``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}) +example: [*content] +--- +The following code example demonstrates how to check that one sequence starts with the same elements as another sequence using `StartsWith`. +[!code-csharp[](SuperLinq/StartsWith/StartsWith2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/StartsWith/StartsWith1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/StartsWith/StartsWith1.linq new file mode 100644 index 00000000..052df5af --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/StartsWith/StartsWith1.linq @@ -0,0 +1,39 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + "BAR", + "foo", + "Baz", + "Qux", + "BAZ", + "FOO", + "bAr", + "baz", + "fOo", + "BaZ", +}; + +// check that sequence starts with a known sequence of values +var result = sequence + .StartsWith(new[] { "BAR", "foo", "Baz", }); + +Console.WriteLine($"StartsWith ['BAR', 'foo', 'Baz']: {result}"); + +result = sequence + .StartsWith(new[] { "bar", "foo", "Baz", }); + +Console.WriteLine($"StartsWith ['bar', 'foo', 'Baz']: {result}"); + +result = sequence + .StartsWith(new[] { "foo", "Baz", }); + +Console.WriteLine($"StartsWith ['foo', 'Baz']: {result}"); + +// This code produces the following output: +// StartsWith ['BAR', 'foo', 'Baz']: True +// StartsWith ['bar', 'foo', 'Baz']: False +// StartsWith ['foo', 'Baz']: False diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/StartsWith/StartsWith2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/StartsWith/StartsWith2.linq new file mode 100644 index 00000000..fe5618e9 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/StartsWith/StartsWith2.linq @@ -0,0 +1,39 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] +{ + "BAR", + "foo", + "Baz", + "Qux", + "BAZ", + "FOO", + "bAr", + "baz", + "fOo", + "BaZ", +}; + +// check that sequence starts with a known sequence of values +var result = sequence + .StartsWith(new[] { "BAR", "foo", "Baz", }, StringComparer.OrdinalIgnoreCase); + +Console.WriteLine($"StartsWith ['BAR', 'foo', 'Baz']: {result}"); + +result = sequence + .StartsWith(new[] { "bar", "foo", "Baz", }, StringComparer.OrdinalIgnoreCase); + +Console.WriteLine($"StartsWith ['bar', 'foo', 'Baz']: {result}"); + +result = sequence + .StartsWith(new[] { "foo", "Baz", }, StringComparer.OrdinalIgnoreCase); + +Console.WriteLine($"StartsWith ['foo', 'Baz']: {result}"); + +// This code produces the following output: +// StartsWith ['BAR', 'foo', 'Baz']: True +// StartsWith ['bar', 'foo', 'Baz']: True +// StartsWith ['foo', 'Baz']: False diff --git a/Source/SuperLinq/StartsWith.cs b/Source/SuperLinq/StartsWith.cs index 360010b3..699c45ee 100644 --- a/Source/SuperLinq/StartsWith.cs +++ b/Source/SuperLinq/StartsWith.cs @@ -3,50 +3,63 @@ public static partial class SuperEnumerable { /// - /// Determines whether the beginning of the first sequence is - /// equivalent to the second sequence, using the default equality - /// comparer. + /// Determines whether the beginning of the first sequence is equivalent to the second sequence, using the + /// default equality comparer. /// - /// Type of elements. - /// The sequence to check. - /// The sequence to compare to. + /// + /// Type of elements. + /// + /// + /// The sequence to check. + /// + /// + /// The sequence to compare to. + /// /// - /// if begins with elements - /// equivalent to . + /// if begins with elements equivalent to . /// /// - /// This is the equivalent of - /// and it calls - /// using - /// on pairs of elements at - /// the same index. + /// + /// This is the equivalent of . + /// + /// + /// This method executes immediately. + /// /// - public static bool StartsWith(this IEnumerable first, IEnumerable second) { return StartsWith(first, second, comparer: null); } /// - /// Determines whether the beginning of the first sequence is - /// equivalent to the second sequence, using the specified element - /// equality comparer. + /// Determines whether the beginning of the first sequence is equivalent to the second sequence, using the + /// specified element equality comparer. /// - /// Type of elements. - /// The sequence to check. - /// The sequence to compare to. - /// Equality comparer to use. + /// + /// Type of elements. + /// + /// + /// The sequence to check. + /// + /// + /// The sequence to compare to. + /// + /// + /// Equality comparer to use. + /// /// - /// if begins with elements - /// equivalent to . + /// if begins with elements equivalent to . /// /// - /// This is the equivalent of - /// and - /// it calls on pairs - /// of elements at the same index. + /// + /// This is the equivalent of . + /// + /// + /// This method executes immediately. + /// /// - public static bool StartsWith(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) { Guard.IsNotNull(first); From f832a392f1b977da3ad05039ca3948b5375b9e78 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 14 Nov 2023 08:22:02 -0600 Subject: [PATCH 090/124] Update documentation for `Subsets` --- .../SuperLinq.SuperEnumerable.Subsets.md | 13 +++ .../apidoc/SuperLinq/Subsets/Subsets1.linq | 37 ++++++++ .../apidoc/SuperLinq/Subsets/Subsets2.linq | 27 ++++++ Source/SuperLinq/Subsets.cs | 88 +++++++++---------- 4 files changed, 121 insertions(+), 44 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Subsets.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Subsets/Subsets1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Subsets/Subsets2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Subsets.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Subsets.md new file mode 100644 index 00000000..e79fad9d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Subsets.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.Subsets``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to get all subsets of a sequence using `Subsets`. +[!code-csharp[](SuperLinq/Subsets/Subsets1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Subsets``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how get all subsets of a particular length using `Subsets`. +[!code-csharp[](SuperLinq/Subsets/Subsets2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Subsets/Subsets1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Subsets/Subsets1.linq new file mode 100644 index 00000000..b855c5ba --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Subsets/Subsets1.linq @@ -0,0 +1,37 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 4); + +// check that sequence starts with a known sequence of values +var result = sequence + .Subsets(); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [], +// [0], +// [1], +// [2], +// [3], +// [0, 1], +// [0, 2], +// [0, 3], +// [1, 2], +// [1, 3], +// [2, 3], +// [0, 1, 2], +// [0, 1, 3], +// [0, 2, 3], +// [1, 2, 3], +// [0, 1, 2, 3] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Subsets/Subsets2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Subsets/Subsets2.linq new file mode 100644 index 00000000..aacbd54b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Subsets/Subsets2.linq @@ -0,0 +1,27 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(0, 4); + +// check that sequence starts with a known sequence of values +var result = sequence + .Subsets(2); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [0, 1], +// [0, 2], +// [0, 3], +// [1, 2], +// [1, 3], +// [2, 3] +// ] diff --git a/Source/SuperLinq/Subsets.cs b/Source/SuperLinq/Subsets.cs index a1025a6a..2fb62086 100644 --- a/Source/SuperLinq/Subsets.cs +++ b/Source/SuperLinq/Subsets.cs @@ -5,23 +5,33 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Returns a sequence of representing all of - /// the subsets of any size that are part of the original sequence. In - /// mathematics, it is equivalent to the power set of a set. + /// Returns a sequence of representing all of the subsets of any size that are part of + /// the original sequence. In mathematics, it is equivalent to the power set of a set. /// + /// + /// Sequence for which to produce subsets + /// + /// + /// The type of the elements in the sequence + /// + /// + /// is + /// + /// + /// A sequence of lists that represent the all subsets of the original sequence + /// /// - /// This operator produces all of the subsets of a given sequence. Subsets are returned - /// in increasing cardinality, starting with the empty set and terminating with the - /// entire original sequence.
- /// Subsets are produced in a deferred, streaming manner; however, each subset is returned - /// as a materialized list.
- /// There are 2^N subsets of a given sequence, where N => sequence.Count(). + /// + /// This operator produces all of the subsets of a given sequence. Subsets are returned in increasing + /// cardinality, starting with the empty set and terminating with the entire original sequence. Subsets are + /// produced in a deferred, streaming manner; however, each subset is returned as a materialized list. There are + /// 2^N subsets of a given sequence, where N = sequence.Count(). + /// + /// + /// This method is implemented by using deferred execution. However, will be + /// consumed in it's entirety immediately when first element of the returned sequence is consumed. + /// ///
- /// Sequence for which to produce subsets - /// The type of the elements in the sequence - /// A sequence of lists that represent the all subsets of the original sequence - /// Thrown if is - public static IEnumerable> Subsets(this IEnumerable sequence) { Guard.IsNotNull(sequence); @@ -55,39 +65,35 @@ static IEnumerable> Core(IEnumerable sequence) } /// - /// Returns a sequence of representing all - /// subsets of a given size that are part of the original sequence. In - /// mathematics, it is equivalent to the combinations or - /// k-subsets of a set. + /// Returns a sequence of representing all subsets of a given size that are part of the + /// original sequence. In mathematics, it is equivalent to the combinations or k-subsets of a + /// set. /// - /// Sequence for which to produce subsets - /// The size of the subsets to produce - /// The type of the elements in the sequence - /// A sequence of lists that represents of K-sized subsets of the original sequence + /// + /// Sequence for which to produce subsets + /// + /// + /// The size of the subsets to produce + /// + /// + /// The type of the elements in the sequence + /// /// - /// Thrown if is + /// is /// /// - /// Thrown if is less than zero. + /// is less than 0. /// - + /// + /// A sequence of lists that represents of K-sized subsets of the original sequence + /// public static IEnumerable> Subsets(this IEnumerable sequence, int subsetSize) { Guard.IsNotNull(sequence); Guard.IsGreaterThanOrEqualTo(subsetSize, 0); - // NOTE: There's an interesting trade-off that we have to make in this operator. - // Ideally, we would throw an exception here if the {subsetSize} parameter is - // greater than the sequence length. Unfortunately, determining the length of a - // sequence is not always possible without enumerating it. Herein lies the rub. - // We want Subsets() to be a deferred operation that only iterates the sequence - // when the caller is ready to consume the results. However, this forces us to - // defer the precondition check on the {subsetSize} upper bound. This can result - // in an exception that is far removed from the point of failure - an unfortunate - // and undesirable outcome. - // At the moment, this operator prioritizes deferred execution over fail-fast - // preconditions. This however, needs to be carefully considered - and perhaps - // may change after further thought and review. + if (sequence.TryGetCollectionCount() is int length) + Guard.IsLessThanOrEqualTo(subsetSize, length); return new SubsetGenerator(sequence, subsetSize); } @@ -119,13 +125,7 @@ private sealed class SubsetEnumerator : IEnumerator> public SubsetEnumerator(IList set, int subsetSize) { - // precondition: subsetSize <= set.Count - if (subsetSize > set.Count) - { - ThrowHelper.ThrowArgumentOutOfRangeException( - nameof(subsetSize), - "Subset size must be <= sequence.Count()"); - } + Guard.IsLessThanOrEqualTo(subsetSize, set.Count); // initialize set arrays... _set = set; From 8bb2e8e55f964809ca226a7413d5cf003af06750 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 14 Nov 2023 11:29:01 -0600 Subject: [PATCH 091/124] Fix documentation bugs --- .../apidoc/SuperLinq.SuperEnumerable.PreScan.md | 2 +- .../apidoc/SuperLinq.SuperEnumerable.Rank.md | 8 ++++---- .../apidoc/SuperLinq.SuperEnumerable.Return.md | 2 +- .../apidoc/SuperLinq.SuperEnumerable.ScanBy.md | 4 ++-- .../apidoc/SuperLinq.SuperEnumerable.ScanRight.md | 12 ++++++------ 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PreScan.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PreScan.md index ce77a26b..8035bfcf 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PreScan.md +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.PreScan.md @@ -3,4 +3,4 @@ uid: SuperLinq.SuperEnumerable.PreScan``1(System.Collections.Generic.IEnumerable example: [*content] --- The following code example demonstrates how to perform an exclusive pre-fix scan on a sequence using `PreScan`. -[!code-csharp[](SuperLinq/PreScan/PreScan1.linq#L6-)] +[!code-csharp[](SuperLinq/PreScan/PreScan.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Rank.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Rank.md index 0b8624db..a3242691 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Rank.md +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Rank.md @@ -17,14 +17,14 @@ uid: SuperLinq.SuperEnumerable.DenseRankBy``2(System.Collections.Generic.IEnumer example: [*content] --- The following code example demonstrates how to rank the items in a sequence according to a key using `DenseRankBy`. -[!code-csharp[](SuperLinq/DenseRank/DenseRankBy1.linq#L6-)] +[!code-csharp[](SuperLinq/DenseRankBy/DenseRankBy1.linq#L6-)] --- uid: SuperLinq.SuperEnumerable.DenseRankBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IComparer{``1}) example: [*content] --- The following code example demonstrates how to rank the items in a sequence according to a key using `DenseRankBy`. -[!code-csharp[](SuperLinq/DenseRank/DenseRankBy3.linq#L6-)] +[!code-csharp[](SuperLinq/DenseRankBy/DenseRankBy3.linq#L6-)] ---- uid: SuperLinq.SuperEnumerable.Rank``1(System.Collections.Generic.IEnumerable{``0}) @@ -45,11 +45,11 @@ uid: SuperLinq.SuperEnumerable.RankBy``2(System.Collections.Generic.IEnumerable{ example: [*content] ---- The following code example demonstrates how to rank the items in a sequence according to a key using `RankBy`. -[!code-csharp[](SuperLinq/Rank/RankBy1.linq#L6-)] +[!code-csharp[](SuperLinq/RankBy/RankBy1.linq#L6-)] ---- uid: SuperLinq.SuperEnumerable.RankBy``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IComparer{``1}) example: [*content] ---- The following code example demonstrates how to rank the items in a sequence according to a key using `RankBy`. -[!code-csharp[](SuperLinq/Rank/RankBy3.linq#L6-)] +[!code-csharp[](SuperLinq/RankBy/RankBy3.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Return.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Return.md index 23899a3a..e0976802 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Return.md +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Return.md @@ -3,4 +3,4 @@ uid: SuperLinq.SuperEnumerable.Return``1(``0) example: [*content] --- The following code example demonstrates how to return a single element as a sequence using `Return`. -[!code-csharp[](SuperLinq/Return/Return1.linq#L6-)] +[!code-csharp[](SuperLinq/Return/Return.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanBy.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanBy.md index 51add0b5..175cac1c 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanBy.md +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanBy.md @@ -1,12 +1,12 @@ --- -uid: ScanBy``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``1,``2},System.Func{``2,``1,``0,``2}) +uid: SuperLinq.SuperEnumerable.ScanBy``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``1,``2},System.Func{``2,``1,``0,``2}) example: [*content] --- The following code example demonstrates how to execute a post-fix scan by key on a sequence using `ScanBy`. [!code-csharp[](SuperLinq/ScanBy/ScanBy1.linq#L6-)] --- -uid: ScanBy``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``1,``2},System.Func{``2,``1,``0,``2},System.Collections.Generic.IEqualityComparer{``1}) +uid: SuperLinq.SuperEnumerable.ScanBy``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``1,``2},System.Func{``2,``1,``0,``2},System.Collections.Generic.IEqualityComparer{``1}) example: [*content] --- The following code example demonstrates how to execute a post-fix scan by key on a sequence using `ScanBy`. diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanRight.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanRight.md index a755deba..36a517a2 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanRight.md +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ScanRight.md @@ -1,13 +1,13 @@ --- -uid: ScanRight``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0}) +uid: SuperLinq.SuperEnumerable.ScanRight``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``0,``0}) example: [*content] --- -The following code example demonstrates how to execute a right-associative post-fix scan by key on a sequence using `ScanRight`. -[!code-csharp[](SuperLinq/ScanBy/ScanBy1.linq#L6-)] +The following code example demonstrates how to execute a right-associative post-fix scan on a sequence using `ScanRight`. +[!code-csharp[](SuperLinq/ScanRight/ScanRight1.linq#L6-)] --- -uid: ScanRight``2(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``0,``1,``1}) +uid: SuperLinq.SuperEnumerable.ScanRight``2(System.Collections.Generic.IEnumerable{``0},``1,System.Func{``0,``1,``1}) example: [*content] --- -The following code example demonstrates how to execute a right-associative post-fix scan by key on a sequence using `ScanRight`. -[!code-csharp[](SuperLinq/ScanBy/ScanBy2.linq#L6-)] +The following code example demonstrates how to execute a right-associative post-fix scan on a sequence using `ScanRight`. +[!code-csharp[](SuperLinq/ScanRight/ScanRight2.linq#L6-)] From 2dadd033244d23fdec919417038ef45e87db03ef Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 14 Nov 2023 14:57:32 -0600 Subject: [PATCH 092/124] Update documentation for `TagFirstLast` --- .../SuperLinq.SuperEnumerable.TagFirstLast.md | 13 ++++ .../SuperLinq/TagFirstLast/TagFirstLast1.linq | 18 +++++ .../SuperLinq/TagFirstLast/TagFirstLast2.linq | 23 ++++++ Source/SuperLinq/TagFirstLast.cs | 78 +++++++++---------- 4 files changed, 90 insertions(+), 42 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TagFirstLast.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/TagFirstLast/TagFirstLast1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/TagFirstLast/TagFirstLast2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TagFirstLast.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TagFirstLast.md new file mode 100644 index 00000000..8028c464 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TagFirstLast.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.TagFirstLast``1(System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how tag elements of a sequence with information on whether it is the first or last element of the sequence using `TagFirstLast`. +[!code-csharp[](SuperLinq/TagFirstLast/TagFirstLast1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.TagFirstLast``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean,System.Boolean,``1}) +example: [*content] +--- +The following code example demonstrates how tag elements of a sequence with information on whether it is the first or last element of the sequence using `TagFirstLast`. +[!code-csharp[](SuperLinq/TagFirstLast/TagFirstLast2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/TagFirstLast/TagFirstLast1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TagFirstLast/TagFirstLast1.linq new file mode 100644 index 00000000..f03d3da5 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TagFirstLast/TagFirstLast1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 4); + +// Replace a value in a sequence +var result = sequence + .TagFirstLast(); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, True, False), (2, False, False), (3, False, False), (4, False, True)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/TagFirstLast/TagFirstLast2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TagFirstLast/TagFirstLast2.linq new file mode 100644 index 00000000..64e8b52c --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TagFirstLast/TagFirstLast2.linq @@ -0,0 +1,23 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 4); + +// Replace a value in a sequence +var result = sequence + .TagFirstLast( + (item, first, last) => new + { + Item = item, + IsEdge = first || last, + }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ Item = 1, IsEdge = True }, { Item = 2, IsEdge = False }, { Item = 3, IsEdge = False }, { Item = 4, IsEdge = True }] diff --git a/Source/SuperLinq/TagFirstLast.cs b/Source/SuperLinq/TagFirstLast.cs index 0eac09e6..59ab5fd5 100644 --- a/Source/SuperLinq/TagFirstLast.cs +++ b/Source/SuperLinq/TagFirstLast.cs @@ -3,64 +3,58 @@ public static partial class SuperEnumerable { /// - /// Returns a sequence resulting from applying a function to each element in the source sequence with additional - /// parameters indicating whether the element is the first and/or last of the sequence. + /// Returns a sequence of tuples containing the element and flags indicating whether the element is the first + /// and/or last of the sequence. /// - /// The type of the elements of . - /// The source sequence. + /// + /// The type of the elements of . + /// + /// + /// The source sequence. + /// /// - /// Returns the resulting sequence. + /// Returns the resulting sequence. /// - /// is . + /// + /// is . + /// /// - /// This operator uses deferred execution and streams its results. + /// + /// This operator uses deferred execution and streams its results. + /// /// - /// - /// - /// The result variable, when iterated over, will yield - /// (item: 123, isFirst: True, isLast: False), - /// (item: 456, isFirst: False, isLast: False) and - /// (item: 789, isFirst: False, isLast: True) in turn. - /// public static IEnumerable<(TSource item, bool isFirst, bool isLast)> TagFirstLast(this IEnumerable source) { return source.TagFirstLast(ValueTuple.Create); } /// - /// Returns a sequence resulting from applying a function to each element in the source sequence with additional - /// parameters indicating whether the element is the first and/or last of the sequence. + /// Returns a sequence resulting from applying a function to each element in the source sequence with additional + /// parameters indicating whether the element is the first and/or last of the sequence. /// - /// The type of the elements of . - /// The type of the element of the returned sequence. - /// The source sequence. - /// A function that determines how to project the each element along with its first or - /// last tag. + /// + /// The type of the elements of . + /// + /// + /// The type of the element of the returned sequence. + /// + /// + /// The source sequence. + /// + /// + /// A function that determines how to project the each element along with its first or last tag. + /// /// - /// Returns the resulting sequence. + /// Returns the resulting sequence. /// - /// or is . + /// + /// or is . + /// /// - /// This operator uses deferred execution and streams its results. + /// + /// This operator uses deferred execution and streams its results. + /// /// - /// - /// new - /// { - /// Number = num, - /// IsFirst = fst, IsLast = lst - /// }); - /// ]]> - /// The result variable, when iterated over, will yield - /// { Number = 123, IsFirst = True, IsLast = False }, - /// { Number = 456, IsFirst = False, IsLast = False } and - /// { Number = 789, IsFirst = False, IsLast = True } in turn. - /// public static IEnumerable TagFirstLast(this IEnumerable source, Func resultSelector) { Guard.IsNotNull(source); From e1906831eebdd5241d89a3e18f8629f5996504b6 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 14 Nov 2023 15:02:25 -0600 Subject: [PATCH 093/124] Update documentation for `TakeEvery` --- .../SuperLinq.SuperEnumerable.TakeEvery.md | 6 ++++ .../apidoc/SuperLinq/TakeEvery/TakeEvery.linq | 18 ++++++++++ Source/SuperLinq/TakeEvery.cs | 36 +++++++++++-------- 3 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TakeEvery.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeEvery/TakeEvery.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TakeEvery.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TakeEvery.md new file mode 100644 index 00000000..38ff560b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TakeEvery.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.TakeEvery``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to take every n-th element of a sequence using `TakeEvery`. +[!code-csharp[](SuperLinq/TakeEvery/TakeEvery.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeEvery/TakeEvery.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeEvery/TakeEvery.linq new file mode 100644 index 00000000..f3bc40dd --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeEvery/TakeEvery.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 6); + +// Take every 2nd element of the sequence +var result = sequence + .TakeEvery(2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 3, 5] diff --git a/Source/SuperLinq/TakeEvery.cs b/Source/SuperLinq/TakeEvery.cs index f270f464..3c3059ec 100644 --- a/Source/SuperLinq/TakeEvery.cs +++ b/Source/SuperLinq/TakeEvery.cs @@ -3,30 +3,36 @@ public static partial class SuperEnumerable { /// - /// Returns every N-th element of a sequence. + /// Returns every N-th element of a sequence. /// - /// Type of the source sequence - /// Source sequence - /// Number of elements to bypass before returning the next element. + /// + /// Type of the source sequence + /// + /// + /// Source sequence + /// + /// + /// Number of elements to bypass before returning the next element. + /// /// - /// A sequence with every N-th element of the input sequence. + /// A sequence with every N-th element of the input sequence. /// - /// is . - /// Thrown if is negative. + /// + /// is . + /// + /// + /// is negative. + /// /// - /// This operator uses deferred execution and streams its results. + /// + /// This operator uses deferred execution and streams its results. + /// /// - /// - /// - /// The result variable, when iterated over, will yield 1, 3 and 5, in turn. - /// public static IEnumerable TakeEvery(this IEnumerable source, int step) { Guard.IsNotNull(source); Guard.IsGreaterThanOrEqualTo(step, 1); + return source.Where((e, i) => i % step == 0); } } From adb0825319a730b93226bcb2b35332a9db92fc36 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 14 Nov 2023 15:13:05 -0600 Subject: [PATCH 094/124] Update documentation for `TakeUntil` --- .../SuperLinq.SuperEnumerable.TakeUntil.md | 6 +++ .../apidoc/SuperLinq/TakeUntil/TakeUntil.linq | 18 +++++++ Source/SuperLinq/TakeUntil.cs | 47 +++++++++++-------- 3 files changed, 51 insertions(+), 20 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TakeUntil.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeUntil/TakeUntil.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TakeUntil.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TakeUntil.md new file mode 100644 index 00000000..20bf8848 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TakeUntil.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.TakeUntil``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to take elements in a sequence until a condition is true using `TakeUntil`. +[!code-csharp[](SuperLinq/TakeUntil/TakeUntil.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeUntil/TakeUntil.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeUntil/TakeUntil.linq new file mode 100644 index 00000000..bfcec15f --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeUntil/TakeUntil.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Take elements until the condition is true +var result = sequence + .TakeUntil(x => x == 5); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [1, 2, 3, 4, 5] diff --git a/Source/SuperLinq/TakeUntil.cs b/Source/SuperLinq/TakeUntil.cs index 72644cb7..44cca1fb 100644 --- a/Source/SuperLinq/TakeUntil.cs +++ b/Source/SuperLinq/TakeUntil.cs @@ -3,35 +3,42 @@ public static partial class SuperEnumerable { /// - /// Returns items from the input sequence until the given predicate returns true - /// when applied to the current source item; that item will be the last returned. + /// Takes items from the input sequence until the given predicate returns when applied to + /// the current source item; that item will be the last taken. /// + /// + /// Type of the source sequence + /// + /// + /// Source sequence + /// + /// + /// Predicate used to determine when to stop yielding results from the source. + /// + /// + /// or is + /// + /// + /// Items from the source sequence until the first returns + /// when applied to the item. + /// /// /// - /// TakeUntil differs from Enumerable.TakeWhile in two respects. Firstly, the sense - /// of the predicate is reversed: it is expected that the predicate will return false - /// to start with, and then return true - for example, when trying to find a matching - /// item in a sequence. + /// TakeUntil differs from in two respects. /// /// - /// Secondly, TakeUntil yields the element which causes the predicate to return true. For - /// example, in a sequence and with a predicate of - /// x == 3]]>, the result would be . + /// Firstly, the sense of the predicate is reversed: it is expected that the predicate will return to start with, and then return - for example, when trying to find + /// a matching item in a sequence. /// /// - /// TakeUntil is as lazy as possible: it will not iterate over the source sequence - /// until it has to, it won't iterate further than it has to, and it won't evaluate - /// the predicate until it has to. (This means that an item may be returned which would - /// actually cause the predicate to throw an exception if it were evaluated, so long as - /// no more items of data are requested.) + /// Secondly, TakeUntil returns the element which causes the predicate to return . /// + /// + /// This operator uses deferred execution and streams its result. + /// /// - /// Type of the source sequence - /// Source sequence - /// Predicate used to determine when to stop yielding results from the source. - /// Items from the source sequence, until the predicate returns true when applied to the item. - /// or is null - public static IEnumerable TakeUntil(this IEnumerable source, Func predicate) { Guard.IsNotNull(source); From 5bd16b5c08746249c9f86db0a65bd43d01f1019a Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 14 Nov 2023 15:27:03 -0600 Subject: [PATCH 095/124] Update documentation for `Throw` --- .../apidoc/SuperLinq.SuperEnumerable.Throw.md | 6 +++++ Source/SuperLinq/Throw.cs | 24 ++++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Throw.md diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Throw.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Throw.md new file mode 100644 index 00000000..ec1435a0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Throw.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Throw``1(System.Exception) +example: [*content] +--- +The following code example demonstrates how to create a sequence that throws on enumeration using `Throw`. +[!code-csharp[](SuperLinq/Catch/Catch1.linq#L6-)] diff --git a/Source/SuperLinq/Throw.cs b/Source/SuperLinq/Throw.cs index 94d4b4b4..e315fbcc 100644 --- a/Source/SuperLinq/Throw.cs +++ b/Source/SuperLinq/Throw.cs @@ -3,19 +3,27 @@ public static partial class SuperEnumerable { /// - /// Returns a sequence that throws an exception upon enumeration. + /// Returns a sequence that throws an exception upon enumeration. /// - /// Source sequence element type. - /// Exception to throw upon enumerating the resulting sequence. - /// Sequence that throws the specified exception upon enumeration. - /// is . + /// + /// Source sequence element type. + /// + /// + /// Exception to throw upon enumerating the resulting sequence. + /// + /// + /// Sequence that throws the specified exception upon enumeration. + /// + /// + /// is . + /// /// /// - /// The provided value () will be thrown when the first element is enumerated. + /// The provided value () will be thrown when the first element is enumerated. /// /// - /// If the returned is enumerated multiple times, the same value will be thrown each - /// time. + /// If the returned is enumerated multiple times, the same value will be thrown + /// each time. /// /// public static IEnumerable Throw(Exception exception) From 9433972820779231a0be550bd894e2390cffbeb0 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 21 Nov 2023 18:31:11 -0600 Subject: [PATCH 096/124] Consistency on order of `` and `` --- Source/SuperLinq/AggregateBy.cs | 12 +++---- Source/SuperLinq/CountMethods.cs | 38 ++++++++++----------- Source/SuperLinq/ElementAt.cs | 12 +++---- Source/SuperLinq/From.cs | 2 +- Source/SuperLinq/GroupAdjacent.cs | 9 ++--- Source/SuperLinq/HasDuplicates.cs | 24 +++++++------- Source/SuperLinq/IBuffer.cs | 14 ++++---- Source/SuperLinq/Identity.cs | 10 ++++-- Source/SuperLinq/Index.cs | 12 +++---- Source/SuperLinq/IndexBy.cs | 15 ++++----- Source/SuperLinq/Insert.cs | 16 ++++----- Source/SuperLinq/Move.cs | 6 ++-- Source/SuperLinq/OnErrorResumeNext.cs | 18 +++++----- Source/SuperLinq/OrderBy.cs | 24 +++++++------- Source/SuperLinq/Pad.cs | 24 +++++++------- Source/SuperLinq/PadStart.cs | 24 +++++++------- Source/SuperLinq/PartialSort.cs | 32 +++++++++--------- Source/SuperLinq/Partition.cs | 15 ++++----- Source/SuperLinq/Permutations.cs | 6 ++-- Source/SuperLinq/PreScan.cs | 6 ++-- Source/SuperLinq/Publish.cs | 6 ++-- Source/SuperLinq/Random.cs | 38 +++++++++------------ Source/SuperLinq/RandomSubset.cs | 12 +++---- Source/SuperLinq/Rank.cs | 48 +++++++++++++-------------- Source/SuperLinq/Replace.cs | 12 +++---- Source/SuperLinq/RunLengthEncode.cs | 12 +++---- Source/SuperLinq/ScanBy.cs | 12 +++---- Source/SuperLinq/Segment.cs | 12 +++---- Source/SuperLinq/Sequence.cs | 6 ++-- 29 files changed, 236 insertions(+), 241 deletions(-) diff --git a/Source/SuperLinq/AggregateBy.cs b/Source/SuperLinq/AggregateBy.cs index 8340e018..21c5eee4 100644 --- a/Source/SuperLinq/AggregateBy.cs +++ b/Source/SuperLinq/AggregateBy.cs @@ -32,13 +32,13 @@ public static partial class SuperEnumerable /// The equality comparer to use to determine whether or not keys are equal. If , the /// default equality comparer for is used. /// + /// + /// A sequence of unique keys and their accumulated value. + /// /// /// , , or is . /// - /// - /// A sequence of unique keys and their accumulated value. - /// /// /// /// This method is implemented by using deferred execution. The operator will be executed in it's entirety @@ -85,13 +85,13 @@ public static IEnumerable> AggregateBy, the /// default equality comparer for is used. /// + /// + /// A sequence of unique keys and their accumulated value. + /// /// /// , , , or is . /// - /// - /// A sequence of unique keys and their accumulated value. - /// /// /// /// This method is implemented by using deferred execution. The operator will be executed in it's entirety diff --git a/Source/SuperLinq/CountMethods.cs b/Source/SuperLinq/CountMethods.cs index 27ccc7d4..528bac83 100644 --- a/Source/SuperLinq/CountMethods.cs +++ b/Source/SuperLinq/CountMethods.cs @@ -15,16 +15,16 @@ public static partial class SuperEnumerable /// /// The minimum number of items a sequence must have for this function to return . /// + /// + /// if the number of elements in the sequence is greater than or equal to the given + /// integer, otherwise. + /// /// /// is . /// /// /// is negative. /// - /// - /// if the number of elements in the sequence is greater than or equal to the given - /// integer, otherwise. - /// /// /// /// This method executes immediately. @@ -50,16 +50,16 @@ public static bool AtLeast(this IEnumerable source, int count) /// /// The maximum number of items a sequence must have for this function to return . /// + /// + /// if the number of elements in the sequence is lesser than or equal to the given + /// integer, otherwise. + /// /// /// is . /// /// /// is negative. /// - /// - /// if the number of elements in the sequence is lesser than or equal to the given - /// integer, otherwise. - /// /// /// /// This method executes immediately. @@ -84,16 +84,16 @@ public static bool AtMost(this IEnumerable source, int count) /// /// The exactly number of items a sequence must have for this function to return . /// + /// + /// if the number of elements in the sequence is equals to the given integer, otherwise. + /// /// /// is . /// /// /// is negative. /// - /// - /// if the number of elements in the sequence is equals to the given integer, otherwise. - /// /// /// /// This method executes immediately. @@ -122,16 +122,16 @@ public static bool Exactly(this IEnumerable source, int count) /// /// The maximum number of items a sequence must have for this function to return . /// + /// + /// if the number of elements in the sequence is between (inclusive) the min and max + /// given integers, otherwise. + /// /// /// is . /// /// /// is negative, or is less than . /// - /// - /// if the number of elements in the sequence is between (inclusive) the min and max - /// given integers, otherwise. - /// /// /// /// This method executes immediately. @@ -170,13 +170,13 @@ private static bool QuantityIterator(IEnumerable source, int limit, int mi /// /// The second sequence. /// - /// - /// or is . - /// /// /// -1 if the first sequence has the fewest elements, 0 if the two sequences have the same number /// of elements or 1 if the first sequence has the most elements. /// + /// + /// or is . + /// /// /// /// This method executes immediately. diff --git a/Source/SuperLinq/ElementAt.cs b/Source/SuperLinq/ElementAt.cs index cdf23f00..730ba2d4 100644 --- a/Source/SuperLinq/ElementAt.cs +++ b/Source/SuperLinq/ElementAt.cs @@ -19,15 +19,15 @@ public static partial class SuperEnumerable /// /// The index of the element to retrieve, which is either from the start or the end. /// + /// + /// The element at the specified position in the sequence. + /// /// /// is . /// /// /// is outside the bounds of the sequence. /// - /// - /// The element at the specified position in the sequence. - /// /// /// /// If the type of implements , that implementation is used to @@ -81,13 +81,13 @@ public static TSource ElementAt(this IEnumerable source, Index /// /// The index of the element to retrieve, which is either from the start or the end. /// - /// - /// is . - /// /// /// if is outside the bounds of the sequence; otherwise, the element at the specified position in the sequence. /// + /// + /// is . + /// /// /// /// If the type of implements , that implementation is used to diff --git a/Source/SuperLinq/From.cs b/Source/SuperLinq/From.cs index 35a9e52c..d19ecb5e 100644 --- a/Source/SuperLinq/From.cs +++ b/Source/SuperLinq/From.cs @@ -124,7 +124,7 @@ static IEnumerable Core(Func function1, Func function2, Func functio /// A sequence with the values resulting from invoking all of the . ///
/// - /// is . + /// is . /// /// /// This operator uses deferred execution and streams the results. If the resulting sequence is enumerated diff --git a/Source/SuperLinq/GroupAdjacent.cs b/Source/SuperLinq/GroupAdjacent.cs index 42dbe1d8..c0cbcd2f 100644 --- a/Source/SuperLinq/GroupAdjacent.cs +++ b/Source/SuperLinq/GroupAdjacent.cs @@ -208,8 +208,8 @@ public static IEnumerable> GroupAdjacent /// - /// A collection of elements of type - /// where each element represents a projection over a group and its key. + /// A collection of elements of type where each element represents a projection + /// over a group and its key. /// /// /// , , or is GroupAdjacent( /// An to compare keys. /// /// - /// A collection of elements of type - /// where each element represents a projection over a group and its key. + /// A collection of elements of type where each element represents a projection + /// over a group and its key. + /// /// /// , , or is . diff --git a/Source/SuperLinq/HasDuplicates.cs b/Source/SuperLinq/HasDuplicates.cs index ac1fc205..3dc2558c 100644 --- a/Source/SuperLinq/HasDuplicates.cs +++ b/Source/SuperLinq/HasDuplicates.cs @@ -11,13 +11,13 @@ public static partial class SuperEnumerable /// /// The sequence to check. /// - /// - /// is . - /// /// /// if any element of the sequence is duplicated, otherwise. /// + /// + /// is . + /// /// /// /// This method executes immediately. @@ -41,13 +41,13 @@ public static bool HasDuplicates(this IEnumerable source) /// The equality comparer to use to determine whether or not keys are equal. If , the /// default equality comparer for is used. /// - /// - /// is . - /// /// /// if any element of the sequence is duplicated, otherwise. /// + /// + /// is . + /// /// /// /// This method executes immediately. @@ -73,13 +73,13 @@ public static bool HasDuplicates(this IEnumerable source, IEqualityCompare /// /// A function to extract the key for each element. /// - /// - /// or is . - /// /// /// if any element of the sequence is duplicated, otherwise. /// + /// + /// or is . + /// /// /// /// This method executes immediately. @@ -110,13 +110,13 @@ public static bool HasDuplicates(this IEnumerable source /// The equality comparer to use to determine whether or not keys are equal. If , the /// default equality comparer for is used. /// - /// - /// or is . - /// /// /// if any element of the sequence is duplicated, otherwise. /// + /// + /// or is . + /// /// /// /// This method executes immediately. diff --git a/Source/SuperLinq/IBuffer.cs b/Source/SuperLinq/IBuffer.cs index e132e3d1..56497b9c 100644 --- a/Source/SuperLinq/IBuffer.cs +++ b/Source/SuperLinq/IBuffer.cs @@ -3,22 +3,24 @@ namespace SuperLinq; /// -/// Represents a cached sequence that can be re-enumerated multiple times. +/// Represents a cached sequence that can be re-enumerated multiple times. /// -/// The type of the items in the cached sequence. +/// +/// The type of the items in the cached sequence. +/// public interface IBuffer : IEnumerable, IDisposable { /// - /// Clears the current buffer and restarts the enumeration from the beginning. + /// Clears the current buffer and restarts the enumeration from the beginning. /// /// - /// Any active iterators of this buffer may receive an when they next due to the invalid state of iteration. + /// Any active iterators of this buffer may receive an when they next + /// due to the invalid state of iteration. /// void Reset(); /// - /// The number of elements currently cached. + /// The number of elements currently cached. /// int Count { get; } } diff --git a/Source/SuperLinq/Identity.cs b/Source/SuperLinq/Identity.cs index a1f2fbcb..30932db8 100644 --- a/Source/SuperLinq/Identity.cs +++ b/Source/SuperLinq/Identity.cs @@ -3,9 +3,13 @@ public static partial class SuperEnumerable { /// - /// Returns the identity function for a given type. + /// Returns the identity function for a given type. /// - /// The type of identity function - /// A reference to the identity function + /// + /// The type of identity function + /// + /// + /// A reference to the identity function + /// public static T Identity(T x) => x; } diff --git a/Source/SuperLinq/Index.cs b/Source/SuperLinq/Index.cs index a71d58b8..d405cf8b 100644 --- a/Source/SuperLinq/Index.cs +++ b/Source/SuperLinq/Index.cs @@ -12,12 +12,12 @@ public static partial class SuperEnumerable /// /// The source sequence. /// - /// - /// is . - /// /// /// A sequence of tuples. /// + /// + /// is . + /// /// /// This operator uses deferred execution and streams its results. /// @@ -39,12 +39,12 @@ public static partial class SuperEnumerable /// /// The index of the first value returned. /// - /// - /// is . - /// /// /// A sequence of tuples. /// + /// + /// is . + /// /// /// This operator uses deferred execution and streams its results. /// diff --git a/Source/SuperLinq/IndexBy.cs b/Source/SuperLinq/IndexBy.cs index 62c8da03..79d21c20 100644 --- a/Source/SuperLinq/IndexBy.cs +++ b/Source/SuperLinq/IndexBy.cs @@ -18,13 +18,13 @@ public static partial class SuperEnumerable /// /// Function that projects the key given an element in the source sequence. /// - /// - /// or is . - /// /// /// A sequence of elements paired with their index within the key-group. The index is the key and the element is /// the value of the pair. /// + /// + /// or is . + /// /// /// /// This operator uses deferred execution and streams its results. @@ -57,16 +57,15 @@ public static partial class SuperEnumerable /// /// /// The equality comparer to use to determine whether or not keys are equal. If , the - /// default equality comparer for - /// is used. + /// default equality comparer for is used. /// - /// - /// or is . - /// /// /// A sequence of elements paired with their index within the key-group. The index is the key and the element is /// the value of the pair. /// + /// + /// or is . + /// /// /// /// This operator uses deferred execution and streams its results. diff --git a/Source/SuperLinq/Insert.cs b/Source/SuperLinq/Insert.cs index 673d2d2c..ec384ea8 100644 --- a/Source/SuperLinq/Insert.cs +++ b/Source/SuperLinq/Insert.cs @@ -17,6 +17,10 @@ public static partial class SuperEnumerable /// /// The zero-based index at which to insert elements from . /// + /// + /// A sequence that contains the elements of plus the elements of inserted at the given index. + /// /// /// or is . /// @@ -27,10 +31,6 @@ public static partial class SuperEnumerable /// Thrown lazily if is greater than the length of . The /// validation occurs when yielding the next element after having iterated entirely. /// - /// - /// A sequence that contains the elements of plus the elements of inserted at the given index. - /// /// /// /// This method uses deferred execution and streams its results. @@ -58,6 +58,10 @@ public static IEnumerable Insert(this IEnumerable first, IEnumerable /// /// The zero-based index at which to insert elements from . /// + /// + /// A sequence that contains the elements of plus the elements of inserted at the given index. + /// /// /// or is . /// @@ -68,10 +72,6 @@ public static IEnumerable Insert(this IEnumerable first, IEnumerable /// Thrown lazily if is greater than the length of . The /// validation occurs when yielding the next element after having iterated entirely. /// - /// - /// A sequence that contains the elements of plus the elements of inserted at the given index. - /// /// /// /// This method uses deferred execution and streams its results. diff --git a/Source/SuperLinq/Move.cs b/Source/SuperLinq/Move.cs index 5cc5b916..1466f04a 100644 --- a/Source/SuperLinq/Move.cs +++ b/Source/SuperLinq/Move.cs @@ -20,15 +20,15 @@ public static partial class SuperEnumerable /// /// The index where the specified range will be moved. /// + /// + /// A sequence with the specified range moved to the new position. + /// /// /// is . /// /// /// , , or is less than 0. /// - /// - /// A sequence with the specified range moved to the new position. - /// /// /// This operator uses deferred execution and streams its results. /// diff --git a/Source/SuperLinq/OnErrorResumeNext.cs b/Source/SuperLinq/OnErrorResumeNext.cs index 0fc59e75..2e5d4d58 100644 --- a/Source/SuperLinq/OnErrorResumeNext.cs +++ b/Source/SuperLinq/OnErrorResumeNext.cs @@ -14,12 +14,12 @@ public static partial class SuperEnumerable /// /// Second sequence. /// - /// - /// or is . - /// /// /// Sequence concatenating the elements of both sequences, ignoring errors. /// + /// + /// or is . + /// /// /// /// is enumerated until either the sequence completes or an error occurs during @@ -47,12 +47,12 @@ public static IEnumerable OnErrorResumeNext(this IEnumerable /// Source sequences. /// - /// - /// is . - /// /// /// Sequence concatenating the elements of the given sequences, ignoring errors. /// + /// + /// is . + /// /// /// /// Each sequence of is enumerated until either the sequence completes or an error occurs during @@ -79,12 +79,12 @@ public static IEnumerable OnErrorResumeNext(params IEnumerable /// /// Source sequences. /// - /// - /// is . - /// /// /// Sequence concatenating the elements of the given sequences, ignoring errors. /// + /// + /// is . + /// /// /// /// Each sequence of is enumerated until either the sequence completes or an error occurs during diff --git a/Source/SuperLinq/OrderBy.cs b/Source/SuperLinq/OrderBy.cs index ab25eaad..00d77a17 100644 --- a/Source/SuperLinq/OrderBy.cs +++ b/Source/SuperLinq/OrderBy.cs @@ -20,12 +20,12 @@ public static partial class SuperEnumerable /// /// A direction in which to order the elements (ascending, descending) /// - /// - /// or is . - /// /// /// An ordered copy of the source sequence /// + /// + /// or is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed @@ -58,12 +58,12 @@ public static IOrderedEnumerable OrderBy(this IEnumerable source, /// /// A direction in which to order the elements (ascending, descending) /// - /// - /// or is . - /// /// /// An ordered copy of the source sequence /// + /// + /// or is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed @@ -97,12 +97,12 @@ public static IOrderedEnumerable OrderBy(this IEnumerable source, /// /// A direction in which to order the elements (ascending, descending) /// - /// - /// or is . - /// /// /// An ordered copy of the source sequence /// + /// + /// or is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed @@ -135,12 +135,12 @@ public static IOrderedEnumerable ThenBy(this IOrderedEnumerable s /// /// A direction in which to order the elements (ascending, descending) /// - /// - /// or is . - /// /// /// An ordered copy of the source sequence /// + /// + /// or is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed diff --git a/Source/SuperLinq/Pad.cs b/Source/SuperLinq/Pad.cs index f206551b..ecdde0ce 100644 --- a/Source/SuperLinq/Pad.cs +++ b/Source/SuperLinq/Pad.cs @@ -14,16 +14,16 @@ public static partial class SuperEnumerable /// /// The width/length below which to pad. /// + /// + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. + /// /// /// is . /// /// /// is less than 0. /// - /// - /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. - /// /// /// This operator uses deferred execution and streams its results. /// @@ -48,16 +48,16 @@ public static partial class SuperEnumerable /// /// The value to use for padding. /// + /// + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. + /// /// /// is . /// /// /// is less than 0. /// - /// - /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. - /// /// /// This operator uses deferred execution and streams its results. /// @@ -81,16 +81,16 @@ public static IEnumerable Pad(this IEnumerable source /// /// A function to generate the value used as padding. /// + /// + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. + /// /// /// or is . /// /// /// is less than 0. /// - /// - /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. - /// /// /// This operator uses deferred execution and streams its results. /// diff --git a/Source/SuperLinq/PadStart.cs b/Source/SuperLinq/PadStart.cs index d1403bf1..f8680489 100644 --- a/Source/SuperLinq/PadStart.cs +++ b/Source/SuperLinq/PadStart.cs @@ -15,16 +15,16 @@ public static partial class SuperEnumerable /// /// The width/length below which to pad. /// + /// + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. + /// /// /// is . /// /// /// is less than 0. /// - /// - /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. - /// /// /// This operator uses deferred execution and streams its results. /// @@ -49,16 +49,16 @@ public static partial class SuperEnumerable /// /// The value to use for padding. /// + /// + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. + /// /// /// is . /// /// /// is less than 0. /// - /// - /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. - /// /// /// This operator uses deferred execution and streams its results. /// @@ -83,16 +83,16 @@ public static IEnumerable PadStart(this IEnumerable s /// /// A function to generate the value used as padding. /// + /// + /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. + /// /// /// or is . /// /// /// is less than 0. /// - /// - /// Returns a sequence that is at least as wide/long as the width/length specified by the parameter. - /// /// /// This operator uses deferred execution and streams its results. /// diff --git a/Source/SuperLinq/PartialSort.cs b/Source/SuperLinq/PartialSort.cs index 8100c8e6..2b9f07ea 100644 --- a/Source/SuperLinq/PartialSort.cs +++ b/Source/SuperLinq/PartialSort.cs @@ -217,16 +217,16 @@ static IEnumerable Core(IEnumerable source, int count, IComparer compar /// /// Number of (maximum) elements to return. /// + /// + /// A sequence containing at most top elements from source, in ascending order of their + /// keys. + /// /// /// or is . /// /// /// is less than 1. /// - /// - /// A sequence containing at most top elements from source, in ascending order of their - /// keys. - /// /// /// /// This operation is an O(n * log(K)) where K is . @@ -265,16 +265,16 @@ public static IEnumerable PartialSortBy( /// /// The direction in which to sort the elements /// + /// + /// A sequence containing at most top elements from source, in the specified order of + /// their keys. + /// /// /// or is . /// /// /// is less than 1. /// - /// - /// A sequence containing at most top elements from source, in the specified order of - /// their keys. - /// /// /// /// This operation is an O(n * log(K)) where K is . @@ -313,16 +313,16 @@ public static IEnumerable PartialSortBy( /// /// A to compare elements. /// + /// + /// A sequence containing at most top elements from source, in ascending order of their + /// keys. + /// /// /// or is . /// /// /// is less than 1. /// - /// - /// A sequence containing at most top elements from source, in ascending order of their - /// keys. - /// /// /// /// This operation is an O(n * log(K)) where K is . @@ -366,16 +366,16 @@ public static IEnumerable PartialSortBy( /// /// The direction in which to sort the elements /// + /// + /// A sequence containing at most top elements from source, in the specified order of + /// their keys. + /// /// /// or is . /// /// /// is less than 1. /// - /// - /// A sequence containing at most top elements from source, in the specified order of - /// their keys. - /// /// /// /// This operation is an O(n * log(K)) where K is . diff --git a/Source/SuperLinq/Partition.cs b/Source/SuperLinq/Partition.cs index 1d4e712e..c0eb7636 100644 --- a/Source/SuperLinq/Partition.cs +++ b/Source/SuperLinq/Partition.cs @@ -14,15 +14,12 @@ public static partial class SuperEnumerable /// /// Type of source elements. /// - /// - /// is . - /// /// /// A tuple of elements satisfying the predicate and those that do not, respectively. /// - /// - /// - /// + /// + /// is . + /// /// /// /// This method executes immediately. @@ -53,13 +50,13 @@ public static (IEnumerable True, IEnumerable False) /// /// Type of the result. /// + /// + /// The return value from . + /// /// /// , , or is . /// - /// - /// The return value from . - /// /// /// /// This method executes immediately. diff --git a/Source/SuperLinq/Permutations.cs b/Source/SuperLinq/Permutations.cs index 4b74b96e..d9cad148 100644 --- a/Source/SuperLinq/Permutations.cs +++ b/Source/SuperLinq/Permutations.cs @@ -187,15 +187,15 @@ private T[] PermuteValueSet() /// /// The original sequence to permute /// + /// + /// A sequence of lists representing permutations of the original sequence + /// /// /// is . /// /// /// has too many elements to permute properly. /// - /// - /// A sequence of lists representing permutations of the original sequence - /// /// /// /// A permutation is a unique re-ordering of the elements of the sequence. diff --git a/Source/SuperLinq/PreScan.cs b/Source/SuperLinq/PreScan.cs index ec861c5f..48a39871 100644 --- a/Source/SuperLinq/PreScan.cs +++ b/Source/SuperLinq/PreScan.cs @@ -17,12 +17,12 @@ public static partial class SuperEnumerable /// /// The initial accumulator value. /// - /// - /// or is . - /// /// /// The scanned sequence /// + /// + /// or is . + /// /// /// /// An exclusive prefix scan returns an equal-length sequence where the N-th element is the aggregation of the diff --git a/Source/SuperLinq/Publish.cs b/Source/SuperLinq/Publish.cs index d112518e..a08fbd26 100644 --- a/Source/SuperLinq/Publish.cs +++ b/Source/SuperLinq/Publish.cs @@ -15,13 +15,13 @@ public static partial class SuperEnumerable /// /// Source sequence. /// - /// - /// is . - /// /// /// Buffer enabling each enumerator to retrieve elements from the shared source sequence, starting from the /// index at the point of obtaining the enumerator. /// + /// + /// is . + /// /// /// /// A separate buffer will be maintained for each created from the returned Random() /// /// Random generator used to produce random numbers /// - /// - /// is . - /// /// /// An infinite sequence of random integers /// + /// + /// is . + /// /// /// /// This operator uses deferred execution and streams its result. @@ -73,12 +73,12 @@ public static IEnumerable Random(int maxValue) /// /// Exclusive upper bound for random values returned /// - /// - /// is . - /// /// /// An infinite sequence of random integers /// + /// + /// is . + /// /// /// /// This operator uses deferred execution and streams its result. @@ -101,12 +101,12 @@ public static IEnumerable Random(Random rand, int maxValue) /// /// Exclusive upper bound for random values returned. /// - /// - /// is greater than . - /// /// /// An infinite sequence of random integers /// + /// + /// is greater than . + /// /// /// /// This operator uses deferred execution and streams its result. @@ -130,15 +130,15 @@ public static IEnumerable Random(int minValue, int maxValue) /// /// Exclusive upper bound for random values returned /// + /// + /// An infinite sequence of random integers + /// /// /// is . /// /// /// is greater than . /// - /// - /// An infinite sequence of random integers - /// /// /// /// This operator uses deferred execution and streams its result. @@ -174,12 +174,12 @@ public static IEnumerable RandomDouble() /// /// Random generator used to produce values /// - /// - /// is . - /// /// /// An infinite sequence of random doubles /// + /// + /// is . + /// /// /// /// This operator uses deferred execution and streams its result. @@ -192,14 +192,6 @@ public static IEnumerable RandomDouble(Random rand) return RandomImpl(rand, r => r.NextDouble()); } - /// - /// This is the underlying implementation that all random operators use to - /// produce a sequence of random values. - /// - /// The type of value returned (either Int32 or Double) - /// Random generators used to produce the sequence - /// Generator function that actually produces the next value - specific to T - /// An infinite sequence of random numbers of type T private static IEnumerable RandomImpl(Random rand, Func nextValue) { while (true) diff --git a/Source/SuperLinq/RandomSubset.cs b/Source/SuperLinq/RandomSubset.cs index 1e8a3c57..9065722c 100644 --- a/Source/SuperLinq/RandomSubset.cs +++ b/Source/SuperLinq/RandomSubset.cs @@ -14,15 +14,15 @@ public static partial class SuperEnumerable /// /// The size of the random subset to return. /// + /// + /// A random sequence of elements in random order from the original sequence. + /// /// /// is . /// /// /// is negative or larger than the length of . /// - /// - /// A random sequence of elements in random order from the original sequence. - /// /// /// /// This method is implemented by using deferred execution. However, will be consumed @@ -49,15 +49,15 @@ public static IEnumerable RandomSubset(this IEnumerable source, int sub /// /// A random generator used as part of the selection algorithm. /// + /// + /// A random sequence of elements in random order from the original sequence. + /// /// /// or is . /// /// /// is negative or larger than the length of . /// - /// - /// A random sequence of elements in random order from the original sequence. - /// /// /// /// This method is implemented by using deferred execution. However, will be consumed diff --git a/Source/SuperLinq/Rank.cs b/Source/SuperLinq/Rank.cs index 0a5bbb42..097f8229 100644 --- a/Source/SuperLinq/Rank.cs +++ b/Source/SuperLinq/Rank.cs @@ -13,12 +13,12 @@ public static partial class SuperEnumerable /// /// The sequence whose items will be ranked /// - /// - /// is . - /// /// /// A sorted sequence of items and their rank. /// + /// + /// is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed @@ -45,12 +45,12 @@ public static partial class SuperEnumerable /// /// A object that defines comparison semantics for the elements in the sequence /// - /// - /// is . - /// /// /// A sorted sequence of items and their rank. /// + /// + /// is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed @@ -80,12 +80,12 @@ public static partial class SuperEnumerable /// /// A key selector function which returns the value by which to rank items in the sequence /// - /// - /// or is . - /// /// /// A sorted sequence of items and their rank. /// + /// + /// or is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed @@ -121,12 +121,12 @@ public static partial class SuperEnumerable /// /// An object that defines the comparison semantics for keys used to rank items /// - /// - /// or is . - /// /// /// A sorted sequence of items and their rank. /// + /// + /// or is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed @@ -154,12 +154,12 @@ public static partial class SuperEnumerable /// /// The sequence whose items will be ranked /// - /// - /// is . - /// /// /// A sorted sequence of items and their rank. /// + /// + /// is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed @@ -185,12 +185,12 @@ public static partial class SuperEnumerable /// /// A object that defines comparison semantics for the elements in the sequence /// - /// - /// is . - /// /// /// A sorted sequence of items and their rank. /// + /// + /// is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed @@ -220,12 +220,12 @@ public static partial class SuperEnumerable /// /// A key selector function which returns the value by which to rank items in the sequence /// - /// - /// or is . - /// /// /// A sorted sequence of items and their rank. /// + /// + /// or is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed @@ -261,12 +261,12 @@ public static partial class SuperEnumerable /// /// An object that defines the comparison semantics for keys used to rank items /// - /// - /// or is . - /// /// /// A sorted sequence of items and their rank. /// + /// + /// or is . + /// /// /// /// This method is implemented by using deferred execution. However, will be consumed diff --git a/Source/SuperLinq/Replace.cs b/Source/SuperLinq/Replace.cs index ea24a58a..cda83804 100644 --- a/Source/SuperLinq/Replace.cs +++ b/Source/SuperLinq/Replace.cs @@ -17,13 +17,13 @@ public static partial class SuperEnumerable /// /// The replacement value to use at . /// - /// - /// is . - /// /// /// A sequence with the original values from , except for position which has the value . /// + /// + /// is . + /// /// /// This operator evaluates in a deferred and streaming manner. /// @@ -65,13 +65,13 @@ static IEnumerable Core( /// /// The replacement value to use at . /// - /// - /// is . - /// /// /// A sequence with the original values from , except for position which has the value . /// + /// + /// is . + /// /// /// This operator evaluates in a deferred and streaming manner. /// diff --git a/Source/SuperLinq/RunLengthEncode.cs b/Source/SuperLinq/RunLengthEncode.cs index d7c888a6..bf09c45a 100644 --- a/Source/SuperLinq/RunLengthEncode.cs +++ b/Source/SuperLinq/RunLengthEncode.cs @@ -12,12 +12,12 @@ public static partial class SuperEnumerable /// /// The sequence to run length encode /// - /// - /// is . - /// /// /// A sequence of tuples containing the element and the occurrence count /// + /// + /// is . + /// /// /// /// This operator evaluates in a deferred and streaming manner. @@ -42,12 +42,12 @@ public static partial class SuperEnumerable /// /// The comparer used to identify equivalent items /// - /// - /// is . - /// /// /// A sequence of tuples containing the element and the occurrence count /// + /// + /// is . + /// /// /// /// This operator evaluates in a deferred and streaming manner. diff --git a/Source/SuperLinq/ScanBy.cs b/Source/SuperLinq/ScanBy.cs index 86b3d769..eaf29aba 100644 --- a/Source/SuperLinq/ScanBy.cs +++ b/Source/SuperLinq/ScanBy.cs @@ -27,13 +27,13 @@ public static partial class SuperEnumerable /// /// An accumulator function invoked for each element. /// + /// + /// A sequence of keys paired with intermediate accumulator states. + /// /// /// , , , or is . /// - /// - /// A sequence of keys paired with intermediate accumulator states. - /// /// /// /// This operator uses deferred execution and streams its result. @@ -77,13 +77,13 @@ public static partial class SuperEnumerable /// The equality comparer to use to determine whether or not keys are equal. If , the /// default equality comparer for is used. /// + /// + /// A sequence of keys paired with intermediate accumulator states. + /// /// /// , , , or is . /// - /// - /// A sequence of keys paired with intermediate accumulator states. - /// /// /// /// This operator uses deferred execution and streams its result. diff --git a/Source/SuperLinq/Segment.cs b/Source/SuperLinq/Segment.cs index f944eb07..1956451e 100644 --- a/Source/SuperLinq/Segment.cs +++ b/Source/SuperLinq/Segment.cs @@ -15,12 +15,12 @@ public static partial class SuperEnumerable /// A function, which returns if the given element begins a new segment, and otherwise /// - /// - /// or is . - /// /// /// A sequence of segment, each of which is a portion of the original sequence /// + /// + /// or is . + /// /// /// /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, @@ -48,12 +48,12 @@ public static IEnumerable> Segment(this IEnumerable source, /// A function, which returns if the given element and index begins a new segment, and /// otherwise /// - /// - /// or is . - /// /// /// A sequence of segment, each of which is a portion of the original sequence /// + /// + /// or is . + /// /// /// /// This method is implemented by using deferred execution and streams the groupings. The grouping elements, diff --git a/Source/SuperLinq/Sequence.cs b/Source/SuperLinq/Sequence.cs index 41399724..891064bc 100644 --- a/Source/SuperLinq/Sequence.cs +++ b/Source/SuperLinq/Sequence.cs @@ -14,13 +14,13 @@ public static partial class SuperEnumerable /// /// The step increment for each returned value. /// + /// + /// An that contains a range of sequential integral numbers. + /// /// /// is less than 0. -or- + ( -1) * /// cannot be contained by an . /// - /// - /// An that contains a range of sequential integral numbers. - /// /// /// /// This operator uses deferred execution and streams its results. From 55326233adbeeb1e92427f7471dc103c3d63443e Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 21 Nov 2023 18:31:45 -0600 Subject: [PATCH 097/124] Add missing tags --- Source/SuperLinq/MaxItems.cs | 18 ++++++++++++++++++ Source/SuperLinq/MinItems.cs | 18 ++++++++++++++++++ Source/SuperLinq/StartsWith.cs | 6 ++++++ 3 files changed, 42 insertions(+) diff --git a/Source/SuperLinq/MaxItems.cs b/Source/SuperLinq/MaxItems.cs index ecfd4984..5e1284f9 100644 --- a/Source/SuperLinq/MaxItems.cs +++ b/Source/SuperLinq/MaxItems.cs @@ -11,6 +11,9 @@ public static partial class SuperEnumerable /// /// The source sequence. /// + /// + /// An containing all of the items that share the maximum value. + /// /// /// is . /// @@ -41,6 +44,9 @@ public static IEnumerable MaxItems(this IEnumerable source) /// /// A to compare elements. /// + /// + /// An containing all of the items that share the maximum value. + /// /// /// is . /// @@ -74,6 +80,9 @@ public static IEnumerable MaxItems(this IEnumerable source, IComparer /// A function to extract a key from an element. /// + /// + /// An containing all of the items that share the maximum value. + /// /// /// is . /// @@ -108,6 +117,9 @@ public static IEnumerable MaxItemsBy(this IEnumerable /// A function to extract a key from an element. /// + /// + /// An containing all of the items that share the maximum value. + /// /// /// is . /// @@ -145,6 +157,9 @@ public static IEnumerable MaxByWithTies(this IEnumerable /// /// A to compare keys. /// + /// + /// An containing all of the items that share the maximum value. + /// /// /// is . /// @@ -182,6 +197,9 @@ public static IEnumerable MaxItemsBy(this IEnumerable /// A to compare keys. /// + /// + /// An containing all of the items that share the maximum value. + /// /// /// is . /// diff --git a/Source/SuperLinq/MinItems.cs b/Source/SuperLinq/MinItems.cs index 6ce62a26..87aae43e 100644 --- a/Source/SuperLinq/MinItems.cs +++ b/Source/SuperLinq/MinItems.cs @@ -11,6 +11,9 @@ public static partial class SuperEnumerable /// /// The source sequence. /// + /// + /// An containing all of the items that share the minimum value. + /// /// /// is . /// @@ -41,6 +44,9 @@ public static IEnumerable MinItems(this IEnumerable source) /// /// A to compare elements. /// + /// + /// An containing all of the items that share the minimum value. + /// /// /// is . /// @@ -74,6 +80,9 @@ public static IEnumerable MinItems(this IEnumerable source, IComparer /// A function to extract a key from an element. /// + /// + /// An containing all of the items that share the minimum value. + /// /// /// is . /// @@ -108,6 +117,9 @@ public static IEnumerable MinItemsBy(this IEnumerable /// A function to extract a key from an element. /// + /// + /// An containing all of the items that share the minimum value. + /// /// /// is . /// @@ -145,6 +157,9 @@ public static IEnumerable MinByWithTies(this IEnumerable /// /// A to compare keys. /// + /// + /// An containing all of the items that share the minimum value. + /// /// /// is . /// @@ -182,6 +197,9 @@ public static IEnumerable MinItemsBy(this IEnumerable /// A to compare keys. /// + /// + /// An containing all of the items that share the minimum value. + /// /// /// is . /// diff --git a/Source/SuperLinq/StartsWith.cs b/Source/SuperLinq/StartsWith.cs index 699c45ee..607d7b25 100644 --- a/Source/SuperLinq/StartsWith.cs +++ b/Source/SuperLinq/StartsWith.cs @@ -19,6 +19,9 @@ public static partial class SuperEnumerable /// if begins with elements equivalent to . /// + /// + /// or is . + /// /// /// /// This is the equivalent of . @@ -52,6 +55,9 @@ public static bool StartsWith(this IEnumerable first, IEnumerable secon /// if begins with elements equivalent to . /// + /// + /// or is . + /// /// /// /// This is the equivalent of . From 6b6bd5f136aa109504b152a3f7b9d766e7ecaee9 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 21 Nov 2023 18:32:20 -0600 Subject: [PATCH 098/124] Clean up whitespace mistakes --- Source/SuperLinq/Lead.cs | 6 ++++-- Source/SuperLinq/OrderByDirection.cs | 6 +++--- Source/SuperLinq/Shuffle.cs | 3 ++- Source/SuperLinq/Split.cs | 1 - 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Source/SuperLinq/Lead.cs b/Source/SuperLinq/Lead.cs index c9ab91d0..42a2ed8b 100644 --- a/Source/SuperLinq/Lead.cs +++ b/Source/SuperLinq/Lead.cs @@ -98,8 +98,10 @@ public static IEnumerable Lead(this IEnumerable /// /// A projection function which accepts the current and subsequent (lead) element (in that order) and produces a - /// result - /// A sequence produced by projecting each element of the sequence with its lead pairing + /// result + /// + /// + /// A sequence produced by projecting each element of the sequence with its lead pairing /// /// /// or is . diff --git a/Source/SuperLinq/OrderByDirection.cs b/Source/SuperLinq/OrderByDirection.cs index 182e1bdb..72b179db 100644 --- a/Source/SuperLinq/OrderByDirection.cs +++ b/Source/SuperLinq/OrderByDirection.cs @@ -1,16 +1,16 @@ namespace SuperLinq; /// -/// Enumeration that defines values representing valid ordering directions for a sequence. +/// Enumeration that defines values representing valid ordering directions for a sequence. /// public enum OrderByDirection { /// - /// Elements are ordered by increasing value + /// Elements are ordered by increasing value /// Ascending = 0, /// - /// Elements are ordered by decreasing value + /// Elements are ordered by decreasing value /// Descending = 1, } diff --git a/Source/SuperLinq/Shuffle.cs b/Source/SuperLinq/Shuffle.cs index 15559585..532d4593 100644 --- a/Source/SuperLinq/Shuffle.cs +++ b/Source/SuperLinq/Shuffle.cs @@ -5,7 +5,8 @@ public static partial class SuperEnumerable /// /// Returns a sequence of elements in random order from the original sequence. /// - /// The type of source sequence elements. + /// + /// The type of source sequence elements. /// /// /// The sequence from which to return random elements. diff --git a/Source/SuperLinq/Split.cs b/Source/SuperLinq/Split.cs index e90ba283..e17de08d 100644 --- a/Source/SuperLinq/Split.cs +++ b/Source/SuperLinq/Split.cs @@ -2,7 +2,6 @@ public static partial class SuperEnumerable { - /// /// Splits the source sequence by a separator. /// From 9d9066d137595e1754c399df4910e0709a97948b Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 21 Nov 2023 18:33:53 -0600 Subject: [PATCH 099/124] Update documenation for `Take` --- Source/SuperLinq/Take.cs | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/Source/SuperLinq/Take.cs b/Source/SuperLinq/Take.cs index 371c573d..76d10b37 100644 --- a/Source/SuperLinq/Take.cs +++ b/Source/SuperLinq/Take.cs @@ -6,15 +6,33 @@ namespace SuperLinq; public static partial class SuperEnumerable { #if !NET6_0_OR_GREATER - /// Returns a specified range of contiguous elements from a sequence. - /// The type of the elements of . - /// The sequence to return elements from. - /// The range of elements to return, which has start and end indexes either from the start or the end. - /// is . - /// An that contains the specified of elements from the sequence. + /// + /// Returns a specified range of contiguous elements from a sequence. + /// + /// + /// The type of the elements of . + /// + /// + /// The sequence to return elements from. + /// + /// + /// The range of elements to return, which has start and end indexes either from the start or the end. + /// + /// + /// is . + /// + /// + /// An that contains the specified of elements from the + /// sequence. + /// /// - /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. - /// enumerates and yields elements whose indices belong to the specified . + /// + /// enumerates and yields elements whose indices belong to the + /// specified . + /// + /// + /// This method is implemented by using deferred execution. + /// /// public static IEnumerable Take(this IEnumerable source, Range range) { From 334ae1682e0e1c6012125bb247f330eee85ec37f Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 21 Nov 2023 18:49:44 -0600 Subject: [PATCH 100/124] Update documentation for `ToDictionary` --- Source/SuperLinq/ToDictionary.cs | 119 ++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 33 deletions(-) diff --git a/Source/SuperLinq/ToDictionary.cs b/Source/SuperLinq/ToDictionary.cs index 68cdf016..6f13f771 100644 --- a/Source/SuperLinq/ToDictionary.cs +++ b/Source/SuperLinq/ToDictionary.cs @@ -3,16 +3,29 @@ public static partial class SuperEnumerable { /// - /// Creates a from a sequence of - /// elements. + /// Creates a from a sequence of + /// elements. /// - /// The type of the key. - /// The type of the value. - /// The source sequence of key-value pairs. + /// + /// The type of the key. + /// + /// + /// The type of the value. + /// + /// + /// The source sequence of key-value pairs. + /// /// - /// A containing the values - /// mapped to their keys. + /// A containing the values mapped to their keys. /// + /// + /// is + /// + /// + /// + /// This method executes immediately. + /// + /// #if NET8_0_OR_GREATER [Obsolete("This method has been implemented by the framework.")] public static Dictionary ToDictionary( @@ -27,18 +40,32 @@ public static Dictionary ToDictionary( } /// - /// Creates a from a sequence of - /// elements. An additional - /// parameter specifies a comparer for keys. + /// Creates a from a sequence of + /// elements. An additional parameter specifies a comparer for keys. /// - /// The type of the key. - /// The type of the value. - /// The source sequence of key-value pairs. - /// The comparer for keys. + /// + /// The type of the key. + /// + /// + /// The type of the value. + /// + /// + /// The source sequence of key-value pairs. + /// + /// + /// The comparer for keys. + /// /// - /// A containing the values - /// mapped to their keys. + /// A containing the values mapped to their keys. /// + /// + /// is + /// + /// + /// + /// This method executes immediately. + /// + /// #if NET8_0_OR_GREATER [Obsolete("This method has been implemented by the framework.")] public static Dictionary ToDictionary( @@ -56,17 +83,29 @@ public static Dictionary ToDictionary( } /// - /// Creates a from a sequence of - /// tuples of 2 where the first item is the key and the second the - /// value. + /// Creates a from a sequence of tuples of 2 where the first item is the + /// key and the second the value. /// - /// The type of the key. - /// The type of the value. - /// The source sequence of couples (tuple of 2). + /// + /// The type of the key. + /// + /// + /// The type of the value. + /// + /// + /// The source sequence of couples (tuple of 2). + /// /// - /// A containing the values - /// mapped to their keys. + /// A containing the values mapped to their keys. /// + /// + /// is + /// + /// + /// + /// This method executes immediately. + /// + /// #if NET8_0_OR_GREATER [Obsolete("This method has been implemented by the framework.")] public static Dictionary ToDictionary( @@ -81,18 +120,32 @@ public static Dictionary ToDictionary( } /// - /// Creates a from a sequence of - /// tuples of 2 where the first item is the key and the second the - /// value. An additional parameter specifies a comparer for keys. + /// Creates a from a sequence of tuples of 2 where the first item is the + /// key and the second the value. An additional parameter specifies a comparer for keys. /// - /// The type of the key. - /// The type of the value. - /// The source sequence of couples (tuple of 2). - /// The comparer for keys. + /// + /// The type of the key. + /// + /// + /// The type of the value. + /// + /// + /// The source sequence of couples (tuple of 2). + /// + /// + /// The comparer for keys. + /// /// - /// A containing the values - /// mapped to their keys. + /// A containing the values mapped to their keys. /// + /// + /// is + /// + /// + /// + /// This method executes immediately. + /// + /// #if NET8_0_OR_GREATER [Obsolete("This method has been implemented by the framework.")] public static Dictionary ToDictionary( From f744224f79f6c0dc80db35d7aff6ca264ab118ae Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 21 Nov 2023 18:50:01 -0600 Subject: [PATCH 101/124] Update documentation for `ValueTupleComparer` --- Source/SuperLinq/ValueTupleComparer.cs | 27 +++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/Source/SuperLinq/ValueTupleComparer.cs b/Source/SuperLinq/ValueTupleComparer.cs index 92646d23..53e5b9da 100644 --- a/Source/SuperLinq/ValueTupleComparer.cs +++ b/Source/SuperLinq/ValueTupleComparer.cs @@ -9,14 +9,27 @@ namespace SuperLinq; internal static class ValueTupleComparer { /// - /// Creates a custom for a - /// based on custom comparers for each component. + /// Creates a custom for a based on custom comparers + /// for each component. /// - /// The type of the first element of the - /// The type of the second element of the - /// The custom comparer for . If , then will be used. - /// The custom comparer for . If , then will be used. - /// An that can be used to compare two using the provided comparers for each component. + /// + /// The type of the first element of the + /// + /// + /// The type of the second element of the + /// + /// + /// The custom comparer for . If , then will be used. + /// + /// + /// The custom comparer for . If , then will be used. + /// + /// + /// An that can be used to compare two using the + /// provided comparers for each component. + /// public static IComparer<(T1, T2)> Create( IComparer? comparer1, IComparer? comparer2) => From 132d2c2de46db2e357177ff46e3e253cb7918050 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 21 Nov 2023 18:50:10 -0600 Subject: [PATCH 102/124] Update documentation for `ValueTupleEqualityComparer` --- .../SuperLinq/ValueTupleEqualityComparer.cs | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/Source/SuperLinq/ValueTupleEqualityComparer.cs b/Source/SuperLinq/ValueTupleEqualityComparer.cs index c3956cd1..acd6e635 100644 --- a/Source/SuperLinq/ValueTupleEqualityComparer.cs +++ b/Source/SuperLinq/ValueTupleEqualityComparer.cs @@ -1,20 +1,26 @@ namespace SuperLinq; /// -/// A utility class to easily compose a custom -/// for s and s. +/// A utility class to easily compose a custom for s +/// and s. /// internal static class ValueTupleEqualityComparer { /// - /// Creates a custom for a based on custom comparers - /// for each component. + /// Creates a custom for a based on custom + /// comparers for each component. /// - /// The type of the first element of the - /// The custom comparer for . If , then will be used. - /// An that can be used to compare two - /// using the provided comparers for each component. + /// + /// The type of the first element of the + /// + /// + /// The custom comparer for . If , then will be used. + /// + /// + /// An that can be used to compare two using the + /// provided comparers for each component. + /// public static IEqualityComparer> Create( IEqualityComparer? comparer1) => comparer1 is null @@ -40,17 +46,27 @@ public int GetHashCode(ValueTuple obj) => } /// - /// Creates a custom for a based on custom - /// comparers for each component. + /// Creates a custom for a based on custom + /// comparers for each component. /// - /// The type of the first element of the - /// The type of the second element of the - /// The custom comparer for . If , then will be used. - /// The custom comparer for . If , then will be used. - /// An that can be used to compare two - /// using the provided comparers for each component. + /// + /// The type of the first element of the + /// + /// + /// The type of the second element of the + /// + /// + /// The custom comparer for . If , then will be used. + /// + /// + /// The custom comparer for . If , then will be used. + /// + /// + /// An that can be used to compare two using + /// the provided comparers for each component. + /// public static IEqualityComparer<(T1, T2)> Create( IEqualityComparer? comparer1, IEqualityComparer? comparer2) => From cdc49e7f2857eae53353224e3be2d82ecf383ecd Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 21 Nov 2023 18:55:57 -0600 Subject: [PATCH 103/124] Update documentation for `Slice` --- .../apidoc/SuperLinq.SuperEnumerable.Slice.md | 6 ++++ .../apidoc/SuperLinq/Slice/Slice.linq | 17 ++++++++++ Source/SuperLinq/Slice.cs | 33 ++++++++++++------- 3 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Slice.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Slice/Slice.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Slice.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Slice.md new file mode 100644 index 00000000..6916d744 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Slice.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Slice``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Int32) +example: [*content] +--- +The following code example demonstrates how to take a range of elements from a sequence using `Slice`. +[!code-csharp[](SuperLinq/Slice/Slice.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Slice/Slice.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Slice/Slice.linq new file mode 100644 index 00000000..6b217236 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Slice/Slice.linq @@ -0,0 +1,17 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Take a slice of the sequence +var result = sequence.Slice(2, 3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [3, 4, 5] diff --git a/Source/SuperLinq/Slice.cs b/Source/SuperLinq/Slice.cs index 44cc16b9..5d9e49ee 100644 --- a/Source/SuperLinq/Slice.cs +++ b/Source/SuperLinq/Slice.cs @@ -3,20 +3,31 @@ public static partial class SuperEnumerable { /// - /// Extracts a contiguous count of elements from a sequence at a particular zero-based starting index + /// Extracts a contiguous count of elements from a sequence at a particular zero-based starting index /// + /// + /// The type of the elements in the source sequence + /// + /// + /// The sequence from which to extract elements + /// + /// + /// The zero-based index at which to begin slicing + /// + /// + /// The number of items to slice out of the index + /// + /// + /// A new sequence containing any elements sliced out from the source sequence + /// + /// + /// is + /// /// - /// If the starting position or count specified result in slice extending past the end of the sequence, - /// it will return all elements up to that point. There is no guarantee that the resulting sequence will - /// contain the number of elements requested - it may have anywhere from 0 to .
- /// This method is implemented in an optimized manner for any sequence implementing .
- /// The result of Slice() is identical to: sequence.Skip(startIndex).Take(count) + /// If the starting position or count specified result in slice extending past the end of the sequence, it will + /// return all elements up to that point. There is no guarantee that the resulting sequence will contain the + /// number of elements requested - it may have anywhere from 0 to . ///
- /// The type of the elements in the source sequence - /// The sequence from which to extract elements - /// The zero-based index at which to begin slicing - /// The number of items to slice out of the index - /// A new sequence containing any elements sliced out from the source sequence [Obsolete("Slice has been replaced by Take(Range).")] public static IEnumerable Slice(this IEnumerable source, int startIndex, int count) { From 6a08b45928392f8b55948bd01ea59a65ad16ed85 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Tue, 21 Nov 2023 19:19:07 -0600 Subject: [PATCH 104/124] Update documentation for `Cartesian` --- .../SuperLinq.SuperEnumerable.Cartesian.md | 98 ++ .../apidoc/SuperLinq/Cartesian/Cartesian.linq | 18 + .../SuperLinq.Generator/Cartesian.sbntxt | 71 +- .../Cartesian.g.cs | 945 ++++++++++++------ 4 files changed, 804 insertions(+), 328 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Cartesian.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Cartesian/Cartesian.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Cartesian.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Cartesian.md new file mode 100644 index 00000000..9717fa48 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Cartesian.md @@ -0,0 +1,98 @@ +--- +uid: SuperLinq.SuperEnumerable.Cartesian``2(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``3(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``3(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Func{``0,``1,``2}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Func{``0,``1,``2,``3}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``5(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Collections.Generic.IEnumerable{``4}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``5(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Func{``0,``1,``2,``3,``4}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``6(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Collections.Generic.IEnumerable{``4},System.Collections.Generic.IEnumerable{``5}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``6(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Collections.Generic.IEnumerable{``4},System.Func{``0,``1,``2,``3,``4,``5}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``7(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Collections.Generic.IEnumerable{``4},System.Collections.Generic.IEnumerable{``5},System.Collections.Generic.IEnumerable{``6}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``7(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Collections.Generic.IEnumerable{``4},System.Collections.Generic.IEnumerable{``5},System.Func{``0,``1,``2,``3,``4,``5,``6}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``8(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Collections.Generic.IEnumerable{``4},System.Collections.Generic.IEnumerable{``5},System.Collections.Generic.IEnumerable{``6},System.Collections.Generic.IEnumerable{``7}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``8(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Collections.Generic.IEnumerable{``4},System.Collections.Generic.IEnumerable{``5},System.Collections.Generic.IEnumerable{``6},System.Func{``0,``1,``2,``3,``4,``5,``6,``7}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Cartesian``9(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Collections.Generic.IEnumerable{``4},System.Collections.Generic.IEnumerable{``5},System.Collections.Generic.IEnumerable{``6},System.Collections.Generic.IEnumerable{``7},System.Func{``0,``1,``2,``3,``4,``5,``6,``7,``8}) +example: [*content] +--- +The following code example demonstrates how to get the cartesian product of multiple sequences using `Cartesian`. +[!code-csharp[](SuperLinq/Cartesian/Cartesian.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Cartesian/Cartesian.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Cartesian/Cartesian.linq new file mode 100644 index 00000000..c59aee9b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Cartesian/Cartesian.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { 1, 2, 3, }; +var seq2 = new[] { "foo", "bar", "quz", }; + +// Take a slice of the sequence +var result = seq1.Cartesian(seq2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(1, foo), (1, bar), (1, quz), (2, foo), (2, bar), (2, quz), (3, foo), (3, bar), (3, quz)] diff --git a/Generators/SuperLinq.Generator/Cartesian.sbntxt b/Generators/SuperLinq.Generator/Cartesian.sbntxt index ecff8c6a..0960d059 100644 --- a/Generators/SuperLinq.Generator/Cartesian.sbntxt +++ b/Generators/SuperLinq.Generator/Cartesian.sbntxt @@ -11,28 +11,37 @@ public static partial class SuperEnumerable { {{~ for $i in 2..($arity.size - 1) ~}} /// - /// Returns the Cartesian product of {{ $arity[$i] }} sequences by enumerating all - /// possible combinations of one item from each sequence, and applying - /// a user-defined projection to the items in a given combination. + /// Returns the Cartesian product of {{ $arity[$i] }} sequences by enumerating all possible combinations of one item from + /// each sequence, and applying a user-defined projection to the items in a given combination. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by - /// . + /// The type of the elements of the result sequence. + ///
+ /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences cached when iterated over. The cache is - /// then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences cached when iterated + /// over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// or any of the input sequences is null. + /// + /// or any of the input sequences is . + /// {{~ for $j in 1..$i ~}} - /// The type of the elements of . - /// The {{ $ordinals[$j] }} sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The {{ $ordinals[$j] }} sequence of elements. + /// {{~ end ~}} public static global::System.Collections.Generic.IEnumerable Cartesian<{{ for $j in 1..$i }}T{{$j}}, {{ end }}TResult>(this {{~ for $j in 1..$i ~}} @@ -74,24 +83,32 @@ public static partial class SuperEnumerable } /// - /// Returns the Cartesian product of {{ $arity[$i] }} sequences by enumerating all - /// possible combinations of one item from each sequence. + /// Returns the Cartesian product of {{ $arity[$i] }} sequences by enumerating all possible combinations of one item from + /// each sequence. /// - /// A sequence of - /// - /// containing elements from each of the sequences. + /// + /// A sequence of containing elements from each of the + /// sequences. + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences are cached when iterated over. The cache - /// is then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences are cached when + /// iterated over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// Any of the input sequences is null. + /// + /// Any of the input sequences is . + /// {{~ for $j in 1..$i ~}} - /// The type of the elements of . - /// The {{ $ordinals[$j] }} sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The {{ $ordinals[$j] }} sequence of elements. + /// {{~ end ~}} public static global::System.Collections.Generic.IEnumerable<({{~ for $j in 1..$i ~}}T{{$j}}{{ if !for.last }},{{ end }}{{ end }})> Cartesian<{{~ for $j in 1..$i ~}}T{{$j}}{{ if !for.last }},{{ end }}{{ end }}>(this diff --git a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/Cartesian.g.cs b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/Cartesian.g.cs index 427a98c2..41371f58 100644 --- a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/Cartesian.g.cs +++ b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/Cartesian.g.cs @@ -3,29 +3,42 @@ public static partial class SuperEnumerable { /// - /// Returns the Cartesian product of two sequences by enumerating all - /// possible combinations of one item from each sequence, and applying - /// a user-defined projection to the items in a given combination. + /// Returns the Cartesian product of two sequences by enumerating all possible combinations of one item from + /// each sequence, and applying a user-defined projection to the items in a given combination. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by - /// . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences cached when iterated over. The cache is - /// then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences cached when iterated + /// over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -43,52 +56,81 @@ public static partial class SuperEnumerable } /// - /// Returns the Cartesian product of two sequences by enumerating all - /// possible combinations of one item from each sequence. + /// Returns the Cartesian product of two sequences by enumerating all possible combinations of one item from + /// each sequence. /// - /// A sequence of - /// - /// containing elements from each of the sequences. + /// + /// A sequence of containing elements from each of the + /// sequences. + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences are cached when iterated over. The cache - /// is then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences are cached when + /// iterated over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(T1, T2)> Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second) => Cartesian(first, second, global::System.ValueTuple.Create); /// - /// Returns the Cartesian product of three sequences by enumerating all - /// possible combinations of one item from each sequence, and applying - /// a user-defined projection to the items in a given combination. + /// Returns the Cartesian product of three sequences by enumerating all possible combinations of one item from + /// each sequence, and applying a user-defined projection to the items in a given combination. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by - /// . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences cached when iterated over. The cache is - /// then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences cached when iterated + /// over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -109,56 +151,93 @@ public static partial class SuperEnumerable } /// - /// Returns the Cartesian product of three sequences by enumerating all - /// possible combinations of one item from each sequence. + /// Returns the Cartesian product of three sequences by enumerating all possible combinations of one item from + /// each sequence. /// - /// A sequence of - /// - /// containing elements from each of the sequences. + /// + /// A sequence of containing elements from each of the + /// sequences. + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences are cached when iterated over. The cache - /// is then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences are cached when + /// iterated over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(T1, T2, T3)> Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third) => Cartesian(first, second, third, global::System.ValueTuple.Create); /// - /// Returns the Cartesian product of four sequences by enumerating all - /// possible combinations of one item from each sequence, and applying - /// a user-defined projection to the items in a given combination. + /// Returns the Cartesian product of four sequences by enumerating all possible combinations of one item from + /// each sequence, and applying a user-defined projection to the items in a given combination. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by - /// . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences cached when iterated over. The cache is - /// then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences cached when iterated + /// over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -182,60 +261,105 @@ public static partial class SuperEnumerable } /// - /// Returns the Cartesian product of four sequences by enumerating all - /// possible combinations of one item from each sequence. + /// Returns the Cartesian product of four sequences by enumerating all possible combinations of one item from + /// each sequence. /// - /// A sequence of - /// - /// containing elements from each of the sequences. + /// + /// A sequence of containing elements from each of the + /// sequences. + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences are cached when iterated over. The cache - /// is then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences are cached when + /// iterated over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(T1, T2, T3, T4)> Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth) => Cartesian(first, second, third, fourth, global::System.ValueTuple.Create); /// - /// Returns the Cartesian product of five sequences by enumerating all - /// possible combinations of one item from each sequence, and applying - /// a user-defined projection to the items in a given combination. + /// Returns the Cartesian product of five sequences by enumerating all possible combinations of one item from + /// each sequence, and applying a user-defined projection to the items in a given combination. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by - /// . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences cached when iterated over. The cache is - /// then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences cached when iterated + /// over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. - /// The type of the elements of . - /// The fifth sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fifth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Collections.Generic.IEnumerable fifth, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -262,64 +386,117 @@ public static partial class SuperEnumerable } /// - /// Returns the Cartesian product of five sequences by enumerating all - /// possible combinations of one item from each sequence. + /// Returns the Cartesian product of five sequences by enumerating all possible combinations of one item from + /// each sequence. /// - /// A sequence of - /// - /// containing elements from each of the sequences. + /// + /// A sequence of containing elements from each of the + /// sequences. + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences are cached when iterated over. The cache - /// is then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences are cached when + /// iterated over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. - /// The type of the elements of . - /// The fifth sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fifth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(T1, T2, T3, T4, T5)> Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Collections.Generic.IEnumerable fifth) => Cartesian(first, second, third, fourth, fifth, global::System.ValueTuple.Create); /// - /// Returns the Cartesian product of six sequences by enumerating all - /// possible combinations of one item from each sequence, and applying - /// a user-defined projection to the items in a given combination. + /// Returns the Cartesian product of six sequences by enumerating all possible combinations of one item from + /// each sequence, and applying a user-defined projection to the items in a given combination. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by - /// . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences cached when iterated over. The cache is - /// then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences cached when iterated + /// over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. - /// The type of the elements of . - /// The fifth sequence of elements. - /// The type of the elements of . - /// The sixth sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fifth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The sixth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Collections.Generic.IEnumerable fifth, global::System.Collections.Generic.IEnumerable sixth, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -349,68 +526,129 @@ public static partial class SuperEnumerable } /// - /// Returns the Cartesian product of six sequences by enumerating all - /// possible combinations of one item from each sequence. + /// Returns the Cartesian product of six sequences by enumerating all possible combinations of one item from + /// each sequence. /// - /// A sequence of - /// - /// containing elements from each of the sequences. + /// + /// A sequence of containing elements from each of the + /// sequences. + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences are cached when iterated over. The cache - /// is then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences are cached when + /// iterated over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. - /// The type of the elements of . - /// The fifth sequence of elements. - /// The type of the elements of . - /// The sixth sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fifth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The sixth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(T1, T2, T3, T4, T5, T6)> Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Collections.Generic.IEnumerable fifth, global::System.Collections.Generic.IEnumerable sixth) => Cartesian(first, second, third, fourth, fifth, sixth, global::System.ValueTuple.Create); /// - /// Returns the Cartesian product of seven sequences by enumerating all - /// possible combinations of one item from each sequence, and applying - /// a user-defined projection to the items in a given combination. + /// Returns the Cartesian product of seven sequences by enumerating all possible combinations of one item from + /// each sequence, and applying a user-defined projection to the items in a given combination. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by - /// . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences cached when iterated over. The cache is - /// then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences cached when iterated + /// over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. - /// The type of the elements of . - /// The fifth sequence of elements. - /// The type of the elements of . - /// The sixth sequence of elements. - /// The type of the elements of . - /// The seventh sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fifth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The sixth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The seventh sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Collections.Generic.IEnumerable fifth, global::System.Collections.Generic.IEnumerable sixth, global::System.Collections.Generic.IEnumerable seventh, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -443,72 +681,141 @@ public static partial class SuperEnumerable } /// - /// Returns the Cartesian product of seven sequences by enumerating all - /// possible combinations of one item from each sequence. + /// Returns the Cartesian product of seven sequences by enumerating all possible combinations of one item from + /// each sequence. /// - /// A sequence of - /// - /// containing elements from each of the sequences. + /// + /// A sequence of containing elements from each of the + /// sequences. + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences are cached when iterated over. The cache - /// is then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences are cached when + /// iterated over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. - /// The type of the elements of . - /// The fifth sequence of elements. - /// The type of the elements of . - /// The sixth sequence of elements. - /// The type of the elements of . - /// The seventh sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fifth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The sixth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The seventh sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Collections.Generic.IEnumerable fifth, global::System.Collections.Generic.IEnumerable sixth, global::System.Collections.Generic.IEnumerable seventh) => Cartesian(first, second, third, fourth, fifth, sixth, seventh, global::System.ValueTuple.Create); /// - /// Returns the Cartesian product of eight sequences by enumerating all - /// possible combinations of one item from each sequence, and applying - /// a user-defined projection to the items in a given combination. + /// Returns the Cartesian product of eight sequences by enumerating all possible combinations of one item from + /// each sequence, and applying a user-defined projection to the items in a given combination. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by - /// . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences cached when iterated over. The cache is - /// then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences cached when iterated + /// over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. - /// The type of the elements of . - /// The fifth sequence of elements. - /// The type of the elements of . - /// The sixth sequence of elements. - /// The type of the elements of . - /// The seventh sequence of elements. - /// The type of the elements of . - /// The eighth sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fifth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The sixth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The seventh sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The eighth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Collections.Generic.IEnumerable fifth, global::System.Collections.Generic.IEnumerable sixth, global::System.Collections.Generic.IEnumerable seventh, global::System.Collections.Generic.IEnumerable eighth, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -544,36 +851,72 @@ public static partial class SuperEnumerable } /// - /// Returns the Cartesian product of eight sequences by enumerating all - /// possible combinations of one item from each sequence. + /// Returns the Cartesian product of eight sequences by enumerating all possible combinations of one item from + /// each sequence. /// - /// A sequence of - /// - /// containing elements from each of the sequences. + /// + /// A sequence of containing elements from each of the + /// sequences. + /// /// /// - /// The method returns items in the same order as a nested foreach - /// loop, but all sequences are cached when iterated over. The cache - /// is then re-used for any subsequent iterations. + /// The method returns items in the same order as a nested foreach loop, but all sequences are cached when + /// iterated over. The cache is then re-used for any subsequent iterations. + ///
/// - /// This method uses deferred execution and stream its results. + /// This method uses deferred execution and stream its results. + ///
///
- /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. - /// The type of the elements of . - /// The fifth sequence of elements. - /// The type of the elements of . - /// The sixth sequence of elements. - /// The type of the elements of . - /// The seventh sequence of elements. - /// The type of the elements of . - /// The eighth sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fifth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The sixth sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The seventh sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The eighth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> Cartesian(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Collections.Generic.IEnumerable fifth, global::System.Collections.Generic.IEnumerable sixth, global::System.Collections.Generic.IEnumerable seventh, global::System.Collections.Generic.IEnumerable eighth) => Cartesian(first, second, third, fourth, fifth, sixth, seventh, eighth, global::System.ValueTuple.Create); } \ No newline at end of file From f3e3f1731ed25f40d35786d24995630c5b1e8012 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 07:24:29 -0600 Subject: [PATCH 105/124] Update documentation for `ToArrayByIndex` --- ...uperLinq.SuperEnumerable.ToArrayByIndex.md | 41 +++ .../ToArrayByIndex/ToArrayByIndex1.linq | 18 ++ .../ToArrayByIndex/ToArrayByIndex2.linq | 18 ++ .../ToArrayByIndex/ToArrayByIndex3.linq | 18 ++ .../ToArrayByIndex/ToArrayByIndex4.linq | 18 ++ .../ToArrayByIndex/ToArrayByIndex5.linq | 18 ++ .../ToArrayByIndex/ToArrayByIndex6.linq | 18 ++ Source/SuperLinq/ToArrayByIndex.cs | 251 +++++++++++------- 8 files changed, 309 insertions(+), 91 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ToArrayByIndex.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex5.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex6.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ToArrayByIndex.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ToArrayByIndex.md new file mode 100644 index 00000000..18486cdb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ToArrayByIndex.md @@ -0,0 +1,41 @@ +--- +uid: SuperLinq.SuperEnumerable.ToArrayByIndex``1(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Int32}) +example: [*content] +--- +The following code example demonstrates how to transform a sequence into an array using indices using `ToArrayByIndex`. +[!code-csharp[](SuperLinq/ToArrayByIndex/ToArrayByIndex1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ToArrayByIndex``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,System.Int32}) +example: [*content] +--- +The following code example demonstrates how to transform a sequence into an array using indices using `ToArrayByIndex`. +[!code-csharp[](SuperLinq/ToArrayByIndex/ToArrayByIndex2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ToArrayByIndex``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Int32},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to transform a sequence into an array using indices using `ToArrayByIndex`. +[!code-csharp[](SuperLinq/ToArrayByIndex/ToArrayByIndex3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ToArrayByIndex``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Int32},System.Func{``0,System.Int32,``1}) +example: [*content] +--- +The following code example demonstrates how to transform a sequence into an array using indices using `ToArrayByIndex`. +[!code-csharp[](SuperLinq/ToArrayByIndex/ToArrayByIndex4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ToArrayByIndex``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,System.Int32},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to transform a sequence into an array using indices using `ToArrayByIndex`. +[!code-csharp[](SuperLinq/ToArrayByIndex/ToArrayByIndex6.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ToArrayByIndex``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,System.Int32},System.Func{``0,System.Int32,``1}) +example: [*content] +--- +The following code example demonstrates how to transform a sequence into an array using indices using `ToArrayByIndex`. +[!code-csharp[](SuperLinq/ToArrayByIndex/ToArrayByIndex5.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex1.linq new file mode 100644 index 00000000..b4a73659 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "alp", "car", }; + +// Transform a sequence by index +var result = sequence + .ToArrayByIndex(c => c[0] - 'a'); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [alp, bar, car, , , foo] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex2.linq new file mode 100644 index 00000000..f9c38a94 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex2.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "alp", "car", }; + +// Transform a sequence by index +var result = sequence + .ToArrayByIndex(26, c => c[0] - 'a'); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [alp, bar, car, , , foo, , , , , , , , , , , , , , , , , , , , ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex3.linq new file mode 100644 index 00000000..167336f1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex3.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "alp", "car", }; + +// Transform a sequence by index +var result = sequence + .ToArrayByIndex(c => c[0] - 'a', c => $"{c[0] - 'a'}:{c}"); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [0:alp, 1:bar, 2:car, , , 5:foo] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex4.linq new file mode 100644 index 00000000..08cb112e --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex4.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "alp", "car", }; + +// Transform a sequence by index +var result = sequence + .ToArrayByIndex(c => c[0] - 'a', (c, i) => $"{i}:{c}"); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [0:alp, 1:bar, 2:car, , , 5:foo] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex5.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex5.linq new file mode 100644 index 00000000..d410c830 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex5.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "alp", "car", }; + +// Transform a sequence by index +var result = sequence + .ToArrayByIndex(26, c => c[0] - 'a', c => $"{c[0] - 'a'}:{c}"); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [0:alp, 1:bar, 2:car, , , 5:foo, , , , , , , , , , , , , , , , , , , , ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex6.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex6.linq new file mode 100644 index 00000000..d8bbced1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex6.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "foo", "bar", "alp", "car", }; + +// Transform a sequence by index +var result = sequence + .ToArrayByIndex(26, c => c[0] - 'a', (c, i) => $"{i}:{c}"); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// One possible random output is as follows: +// [0:alp, 1:bar, 2:car, , , 5:foo, , , , , , , , , , , , , , , , , , , , ] diff --git a/Source/SuperLinq/ToArrayByIndex.cs b/Source/SuperLinq/ToArrayByIndex.cs index 9d1a4918..8d4ca5df 100644 --- a/Source/SuperLinq/ToArrayByIndex.cs +++ b/Source/SuperLinq/ToArrayByIndex.cs @@ -3,25 +3,33 @@ public static partial class SuperEnumerable { /// - /// Creates an array from an where a function is used to determine the index at which - /// an element will be placed in the array. + /// Creates an array from an where a function is used to determine the index at + /// which an element will be placed in the array. /// - /// The source sequence for the array. + /// + /// The source sequence for the array. + /// /// - /// A function that maps an element to its index. + /// A function that maps an element to its index. + /// /// - /// The type of the element in . + /// The type of the element in . + /// /// - /// An array that contains the elements from . The size of the array will be as large as - /// the highest index returned by the plus 1. + /// An array that contains the elements from . The size of the array will be as large + /// as the highest index returned by the plus 1. /// - /// or is . - /// An index returned by is less than - /// 0. + /// + /// or is . + /// + /// + /// An index returned by is less than 0. + /// /// - /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one - /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// + /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one + /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// /// public static T?[] ToArrayByIndex( this IEnumerable source, @@ -31,29 +39,41 @@ public static partial class SuperEnumerable } /// - /// Creates an array from an where a function is used to determine the index at which - /// an element will be placed in the array. The elements are projected into the array via an additional function. + /// Creates an array from an where a function is used to determine the index at + /// which an element will be placed in the array. The elements are projected into the array via an additional + /// function. /// - /// The source sequence for the array. + /// + /// The source sequence for the array. + /// /// - /// A function that maps an element to its index. + /// A function that maps an element to its index. + /// /// - /// A function to project a source element into an element of the resulting array. + /// A function to project a source element into an element of the resulting array. + /// /// - /// The type of the element in . + /// The type of the element in . + /// /// - /// The type of the element in the resulting array. + /// The type of the element in the resulting array. + /// /// - /// An array that contains the projected elements from . The size of the array will be as - /// large as the highest index returned by the plus 1. + /// An array that contains the projected elements from . The size of the array will be + /// as large as the highest index returned by the plus 1. /// - /// , , or - /// is . - /// An index returned by is less than - /// 0. + /// + /// , , or is . + /// + /// + /// An index returned by is less than 0. + /// /// - /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one - /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// + /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one + /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// /// public static TResult?[] ToArrayByIndex( this IEnumerable source, @@ -65,29 +85,41 @@ public static partial class SuperEnumerable } /// - /// Creates an array from an where a function is used to determine the index at which - /// an element will be placed in the array. The elements are projected into the array via an additional function. + /// Creates an array from an where a function is used to determine the index at + /// which an element will be placed in the array. The elements are projected into the array via an additional + /// function. /// - /// The source sequence for the array. + /// + /// The source sequence for the array. + /// /// - /// A function that maps an element to its index. + /// A function that maps an element to its index. + /// /// - /// A function to project a source element into an element of the resulting array. + /// A function to project a source element into an element of the resulting array. + /// /// - /// The type of the element in . + /// The type of the element in . + /// /// - /// The type of the element in the resulting array. + /// The type of the element in the resulting array. + /// /// - /// An array that contains the projected elements from . The size of the array will be as - /// large as the highest index returned by the plus 1. + /// An array that contains the projected elements from . The size of the array will be + /// as large as the highest index returned by the plus 1. /// - /// , , or - /// is . - /// An index returned by is less than - /// 0. + /// + /// , , or is . + /// + /// + /// An index returned by is less than 0. + /// /// - /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one - /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// + /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one + /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// /// public static TResult?[] ToArrayByIndex( this IEnumerable source, @@ -122,26 +154,36 @@ public static partial class SuperEnumerable } /// - /// Creates an array of user-specified length from an where a function is used to - /// determine the index at which an element will be placed in the array. + /// Creates an array of user-specified length from an where a function is used to + /// determine the index at which an element will be placed in the array. /// - /// The source sequence for the array. - /// The (non-negative) length of the resulting array. + /// + /// The source sequence for the array. + /// + /// + /// The (non-negative) length of the resulting array. + /// /// - /// A function that maps an element to its index. + /// A function that maps an element to its index. + /// /// - /// The type of the element in . + /// The type of the element in . + /// /// - /// An array of size that contains the elements from . + /// An array of size that contains the elements from . /// - /// or is . - /// is less than 0. -or- An index - /// returned by is invalid for an array of size . + /// + /// or is . + /// + /// + /// is less than 0. -or- An index returned by + /// is invalid for an array of size . + /// /// - /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one - /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// + /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one + /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// /// public static T?[] ToArrayByIndex( this IEnumerable source, @@ -152,31 +194,45 @@ public static partial class SuperEnumerable } /// - /// Creates an array of user-specified length from an where a function is used to - /// determine the index at which an element will be placed in the array. The elements are projected into the array - /// via an additional function. + /// Creates an array of user-specified length from an where a function is used to + /// determine the index at which an element will be placed in the array. The elements are projected into the + /// array via an additional function. /// - /// The source sequence for the array. - /// The (non-negative) length of the resulting array. + /// + /// The source sequence for the array. + /// + /// + /// The (non-negative) length of the resulting array. + /// /// - /// A function that maps an element to its index. + /// A function that maps an element to its index. + /// /// - /// A function to project a source element into an element of the resulting array. + /// A function to project a source element into an element of the resulting array. + /// /// - /// The type of the element in . + /// The type of the element in . + /// /// - /// The type of the element in the resulting array. + /// The type of the element in the resulting array. + /// /// - /// An array of size that contains the projected elements from . + /// An array of size that contains the projected elements from . /// - /// , , is . - /// is less than 0. -or- An index - /// returned by is invalid for an array of size . + /// + /// , , is . + /// + /// + /// is less than 0. -or- An index returned by + /// is invalid for an array of size . + /// /// - /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one - /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// + /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one + /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// /// public static TResult?[] ToArrayByIndex( this IEnumerable source, @@ -189,31 +245,44 @@ public static partial class SuperEnumerable } /// - /// Creates an array of user-specified length from an where a function is used to - /// determine the index at which an element will be placed in the array. The elements are projected into the array - /// via an additional function. + /// Creates an array of user-specified length from an where a function is used to + /// determine the index at which an element will be placed in the array. The elements are projected into the + /// array via an additional function. /// - /// The source sequence for the array. - /// The (non-negative) length of the resulting array. + /// + /// The source sequence for the array. + /// + /// + /// The (non-negative) length of the resulting array. + /// /// - /// A function that maps an element to its index. + /// A function that maps an element to its index. + /// /// - /// A function to project a source element into an element of the resulting array. + /// A function to project a source element into an element of the resulting array. + /// /// - /// The type of the element in . + /// The type of the element in . + /// /// - /// The type of the element in the resulting array. + /// The type of the element in the resulting array. + /// /// - /// An array of size that contains the projected elements from the input sequence. + /// An array of size that contains the projected elements from the input sequence. /// - /// , , is . - /// is less than 0. -or- An index - /// returned by is invalid for an array of size . + /// + /// , , is . + /// + /// + /// is less than 0. -or- An index returned by + /// is invalid for an array of size . + /// /// - /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one - /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// + /// This method forces immediate query evaluation. It should not be used on infinite sequences. If more than one + /// element maps to the same index then the latter element overwrites the former in the resulting array. + /// /// public static TResult?[] ToArrayByIndex( this IEnumerable source, From a795965c96a8c0877f32ecc0639d1253af2fe3d3 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 07:25:35 -0600 Subject: [PATCH 106/124] Update documentation for `ToDataTable` --- Source/SuperLinq/ToDataTable.cs | 113 ++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 34 deletions(-) diff --git a/Source/SuperLinq/ToDataTable.cs b/Source/SuperLinq/ToDataTable.cs index 261b2b10..7ef45b66 100644 --- a/Source/SuperLinq/ToDataTable.cs +++ b/Source/SuperLinq/ToDataTable.cs @@ -7,17 +7,29 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Appends elements in the sequence as rows of a given object. + /// Appends elements in the sequence as rows of a given object. /// - /// The type of the elements of . - /// - /// The source. - /// + /// + /// The type of the elements of . + /// + /// + /// The type of the in which to store data. + /// + /// + /// The source. + /// + /// + /// A to hold the data from . + /// /// - /// A or subclass representing the source. + /// The value passed in as . /// - /// This operator uses immediate execution. - + /// + /// or is + /// + /// + /// This operator uses immediate execution. + /// public static TTable ToDataTable(this IEnumerable source, TTable table) where TTable : DataTable { @@ -25,53 +37,86 @@ public static TTable ToDataTable(this IEnumerable source, TTable t } /// - /// Appends elements in the sequence as rows of a given - /// object with a set of lambda expressions specifying which members (property - /// or field) of each element in the sequence will supply the column values. + /// Appends elements in the sequence as rows of a given object with a set of lambda + /// expressions specifying which members (property or field) of each element in the sequence will supply the + /// column values. /// - /// The type of the elements of . - /// The source. - /// Expressions providing access to element members. + /// + /// The type of the elements of . + /// + /// + /// The source. + /// + /// + /// Expressions providing access to element members. + /// /// - /// A representing the source. + /// A representing the source. /// - /// This operator uses immediate execution. - + /// + /// is + /// + /// + /// This operator uses immediate execution. + /// public static DataTable ToDataTable(this IEnumerable source, params Expression>[] expressions) { return ToDataTable(source, new DataTable(), expressions); } /// - /// Converts a sequence to a object. + /// Converts a sequence to a object. /// - /// The type of the elements of . - /// The source. + /// + /// The type of the elements of . + /// + /// + /// The source. + /// /// - /// A representing the source. + /// A representing the source. /// - /// This operator uses immediate execution. - + /// + /// is + /// + /// + /// This operator uses immediate execution. + /// public static DataTable ToDataTable(this IEnumerable source) { return ToDataTable(source, new DataTable(), []); } /// - /// Appends elements in the sequence as rows of a given - /// object with a set of lambda expressions specifying which members (property - /// or field) of each element in the sequence will supply the column values. + /// Appends elements in the sequence as rows of a given object with a set of lambda + /// expressions specifying which members (property or field) of each element in the sequence will supply the + /// column values. /// - /// The type of the elements of . - /// The type of the input and resulting object. - /// The source. - /// The type of object where to add rows - /// Expressions providing access to element members. + /// + /// The type of the elements of . + /// + /// + /// The type of the in which to store data. + /// + /// + /// The source. + /// + /// + /// A to hold the data from . + /// + /// + /// Expressions providing access to element members. + /// /// - /// A or subclass representing the source. + /// The value passed in as . /// - /// This operator uses immediate execution. - + /// + /// , , or is + /// + /// + /// This operator uses immediate execution. + /// public static TTable ToDataTable(this IEnumerable source, TTable table, params Expression>[] expressions) where TTable : DataTable { From d6fbae6b0128bf365c7b7a4070abe513a4a37431 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 07:26:03 -0600 Subject: [PATCH 107/124] Update documentation for `ToLookup` --- Source/SuperLinq/ToLookup.cs | 143 ++++++++++++++++++++++++----------- 1 file changed, 100 insertions(+), 43 deletions(-) diff --git a/Source/SuperLinq/ToLookup.cs b/Source/SuperLinq/ToLookup.cs index 1946dc0d..e153ecf6 100644 --- a/Source/SuperLinq/ToLookup.cs +++ b/Source/SuperLinq/ToLookup.cs @@ -3,35 +3,64 @@ public static partial class SuperEnumerable { /// - /// Creates a from a sequence of - /// elements. + /// Creates an from a sequence of + /// elements. /// - /// The type of the key. - /// The type of the value. - /// The source sequence of key-value pairs. + /// + /// The type of the key. + /// + /// + /// The type of the value. + /// + /// + /// The source sequence of key-value pairs. + /// /// - /// A containing the values - /// mapped to their keys. + /// An containing the values mapped to their keys. /// - - public static ILookup ToLookup(this IEnumerable> source) => - source.ToLookup(null); + /// + /// is + /// + /// + /// + /// This method executes immediately. + /// + /// + public static ILookup ToLookup( + this IEnumerable> source) + { + return source.ToLookup(null); + } /// - /// Creates a from a sequence of - /// elements. An additional - /// parameter specifies a comparer for keys. + /// Creates an from a sequence of + /// elements. An additional parameter specifies a comparer for keys. /// - /// The type of the key. - /// The type of the value. - /// The source sequence of key-value pairs. - /// The comparer for keys. + /// + /// The type of the key. + /// + /// + /// The type of the value. + /// + /// + /// The source sequence of key-value pairs. + /// + /// + /// The comparer for keys. + /// /// - /// A containing the values - /// mapped to their keys. + /// An containing the values mapped to their keys. /// - - public static ILookup ToLookup(this IEnumerable> source, + /// + /// is + /// + /// + /// + /// This method executes immediately. + /// + /// + public static ILookup ToLookup( + this IEnumerable> source, IEqualityComparer? comparer) { Guard.IsNotNull(source); @@ -39,36 +68,64 @@ public static ILookup ToLookup(this IEnumerable - /// Creates a from a sequence of - /// tuples of 2 where the first item is the key and the second the - /// value. + /// Creates an /> from a sequence of tuples of 2 where the first item is the + /// key and the second the value. /// - /// The type of the key. - /// The type of the value. - /// The source sequence of tuples of 2. + /// + /// The type of the key. + /// + /// + /// The type of the value. + /// + /// + /// The source sequence of tuples of 2. + /// /// - /// A containing the values - /// mapped to their keys. + /// An containing the values mapped to their keys. /// - - public static ILookup ToLookup(this IEnumerable<(TKey Key, TValue Value)> source) => - source.ToLookup(null); + /// + /// is + /// + /// + /// + /// This method executes immediately. + /// + /// + public static ILookup ToLookup( + this IEnumerable<(TKey Key, TValue Value)> source) + { + return source.ToLookup(null); + } /// - /// Creates a from a sequence of - /// tuples of 2 where the first item is the key and the second the - /// value. An additional parameter specifies a comparer for keys. + /// Creates an from a sequence of tuples of 2 where the first item is the + /// key and the second the value. An additional parameter specifies a comparer for keys. /// - /// The type of the key. - /// The type of the value. - /// The source sequence of tuples of 2. - /// The comparer for keys. + /// + /// The type of the key. + /// + /// + /// The type of the value. + /// + /// + /// The source sequence of tuples of 2. + /// + /// + /// The comparer for keys. + /// /// - /// A containing the values - /// mapped to their keys. + /// An containing the values mapped to their keys. /// - - public static ILookup ToLookup(this IEnumerable<(TKey Key, TValue Value)> source, + /// + /// is + /// + /// + /// + /// This method executes immediately. + /// + /// + public static ILookup ToLookup( + this IEnumerable<(TKey Key, TValue Value)> source, IEqualityComparer? comparer) { Guard.IsNotNull(source); From 3e87aeb18d50588c329032b03ad082baa3d98aa1 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 09:55:02 -0600 Subject: [PATCH 108/124] Update documentation for `ToDelimitedString` --- .../ToDelimitedString.sbntxt | 22 +- .../ToDelimitedString.g.cs | 308 ++++++++++-------- Source/SuperLinq/ToDelimitedString.cs | 26 +- 3 files changed, 194 insertions(+), 162 deletions(-) diff --git a/Generators/SuperLinq.Generator/ToDelimitedString.sbntxt b/Generators/SuperLinq.Generator/ToDelimitedString.sbntxt index d0378724..c7ab7595 100644 --- a/Generators/SuperLinq.Generator/ToDelimitedString.sbntxt +++ b/Generators/SuperLinq.Generator/ToDelimitedString.sbntxt @@ -6,22 +6,24 @@ public static partial class SuperEnumerable { {{~ for t in types ~}} /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable<{{t}}> source, global::System.String delimiter) { diff --git a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ToDelimitedString.g.cs b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ToDelimitedString.g.cs index 10d60892..e39fcce2 100644 --- a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ToDelimitedString.g.cs +++ b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ToDelimitedString.g.cs @@ -3,22 +3,24 @@ public static partial class SuperEnumerable { /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -29,22 +31,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -55,22 +59,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -81,22 +87,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -107,22 +115,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -133,22 +143,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -159,22 +171,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -185,22 +199,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -211,22 +227,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -237,22 +255,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -263,22 +283,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -289,22 +311,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -315,22 +339,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { @@ -341,22 +367,24 @@ public static partial class SuperEnumerable } /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() + /// conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . + /// If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// public static global::System.String ToDelimitedString(this global::System.Collections.Generic.IEnumerable source, global::System.String delimiter) { diff --git a/Source/SuperLinq/ToDelimitedString.cs b/Source/SuperLinq/ToDelimitedString.cs index 370d4f9c..2fd5a3d6 100644 --- a/Source/SuperLinq/ToDelimitedString.cs +++ b/Source/SuperLinq/ToDelimitedString.cs @@ -5,25 +5,27 @@ namespace SuperLinq; public static partial class SuperEnumerable { /// - /// Creates a delimited string from a sequence of values and - /// a given delimiter. + /// Creates a delimited string from a sequence of values and a given delimiter. /// - /// Type of element in the source sequence - /// The sequence of items to delimit. Each is converted to a string using the - /// simple ToString() conversion. - /// The delimiter to inject between elements. + /// + /// Type of element in the source sequence + /// + /// + /// The sequence of items to delimit. Each is converted to a string using the simple ToString() conversion. + /// + /// + /// The delimiter to inject between elements. + /// /// - /// A string that consists of the elements in - /// delimited by . If the source sequence - /// is empty, the method returns an empty string. + /// A string that consists of the elements in delimited by . If the source sequence is empty, the method returns an empty string. /// /// - /// or is . + /// or is . /// /// - /// This operator uses immediate execution and effectively buffers the sequence. + /// This operator uses immediate execution and effectively buffers the sequence. /// - public static string ToDelimitedString(this IEnumerable source, string delimiter) { Guard.IsNotNull(source); From 72dccf7fbf3e80096505cdd90ffbe43fc66620bf Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 09:58:11 -0600 Subject: [PATCH 109/124] Update documentation for `Transpose` --- .../SuperLinq.SuperEnumerable.Transpose.md | 6 +++ .../apidoc/SuperLinq/Transpose/Transpose.linq | 28 ++++++++++++++ Source/SuperLinq/Transpose.cs | 38 ++++++++----------- 3 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Transpose.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Transpose/Transpose.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Transpose.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Transpose.md new file mode 100644 index 00000000..8b294a46 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Transpose.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Transpose``1(System.Collections.Generic.IEnumerable{System.Collections.Generic.IEnumerable{``0}}) +example: [*content] +--- +The following code example demonstrates how to transpose a jagged 2d sequence using `Transpose`. +[!code-csharp[](SuperLinq/Transpose/Transpose.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Transpose/Transpose.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Transpose/Transpose.linq new file mode 100644 index 00000000..aae88948 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Transpose/Transpose.linq @@ -0,0 +1,28 @@ + + SuperLinq + SuperLinq + + +var matrix = new[] +{ + new[] { 10, 11 }, + new[] { 20 }, + new[] { 30, 31, 32 } +}; + +// Transpose a 2d sequence +var result = matrix.Transpose(); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// One possible random output is as follows: +// [ +// [10, 20, 30], +// [11, 31], +// [32] +// ] diff --git a/Source/SuperLinq/Transpose.cs b/Source/SuperLinq/Transpose.cs index 7f9d1415..91dada4b 100644 --- a/Source/SuperLinq/Transpose.cs +++ b/Source/SuperLinq/Transpose.cs @@ -3,34 +3,26 @@ public static partial class SuperEnumerable { /// - /// Transposes a sequence of rows into a sequence of columns. + /// Transposes a sequence of rows into a sequence of columns. /// - /// Type of source sequence elements. - /// Source sequence to transpose. + /// + /// Type of source sequence elements. + /// + /// + /// Source sequence to transpose. + /// /// - /// Returns a sequence of columns in the source swapped into rows. + /// Returns a sequence of columns in the source swapped into rows. /// - /// is . + /// + /// is . + /// /// - /// If a rows is shorter than a follow it then the shorter row's - /// elements are skipped in the corresponding column sequences. - /// This operator uses deferred execution and streams its results. - /// Source sequence is consumed greedily when an iteration begins. - /// The inner sequences representing rows are consumed lazily and - /// resulting sequences of columns are streamed. + /// If a rows is shorter than a follow it then the shorter row's elements are skipped in the corresponding + /// column sequences. This operator uses deferred execution and streams its results. Source sequence is consumed + /// greedily when an iteration begins. The inner sequences representing rows are consumed lazily and resulting + /// sequences of columns are streamed. /// - /// - /// - /// The result variable will contain [[10, 20, 30], [11, 31], [32]]. - /// public static IEnumerable> Transpose(this IEnumerable> source) { Guard.IsNotNull(source); From e484718c0c0a0000a26402b72c096903a95c2e25 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 10:23:23 -0600 Subject: [PATCH 110/124] Update documentation for `Traverse` --- .../SuperLinq.SuperEnumerable.Traverse.md | 13 ++++ .../TraverseBreadthFirst.linq | 40 +++++++++++ .../TraverseDepthFirst.linq | 40 +++++++++++ Source/SuperLinq/Traverse.cs | 70 +++++++++++-------- 4 files changed, 135 insertions(+), 28 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Traverse.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/TraverseBreadthFirst/TraverseBreadthFirst.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/TraverseDepthFirst/TraverseDepthFirst.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Traverse.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Traverse.md new file mode 100644 index 00000000..62709263 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Traverse.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.TraverseBreadthFirst``1(``0,System.Func{``0,System.Collections.Generic.IEnumerable{``0}}) +example: [*content] +--- +The following code example demonstrates how to traverse a tree breadth-first using `TraverseBreadthFirst`. +[!code-csharp[](SuperLinq/TraverseBreadthFirst/TraverseBreadthFirst.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.TraverseDepthFirst``1(``0,System.Func{``0,System.Collections.Generic.IEnumerable{``0}}) +example: [*content] +--- +The following code example demonstrates how to traverse a tree depth-first using `TraverseDepthFirst`. +[!code-csharp[](SuperLinq/TraverseDepthFirst/TraverseDepthFirst.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/TraverseBreadthFirst/TraverseBreadthFirst.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TraverseBreadthFirst/TraverseBreadthFirst.linq new file mode 100644 index 00000000..6202d2af --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TraverseBreadthFirst/TraverseBreadthFirst.linq @@ -0,0 +1,40 @@ + + SuperLinq + SuperLinq + + +Node root = new(0, +[ + new(1), new(2), new(3), + new(4, + [ + new(5), new(6), + new(7, [ new(8), new(9) ]), + new(10, [ new(11) ]), + ]), + new(11), + new(12, + [ + new(13), new(14), + new(15, [ new(16), new(17) ]), + new(18), + ]), + new(19), new(20), +]); + +// Traverse a tree +var result = SuperEnumerable + .TraverseBreadthFirst( + root, + static x => x.Children ?? []) + .Select(x => x.Id); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [0, 1, 2, 3, 4, 11, 12, 19, 20, 5, 6, 7, 10, 13, 14, 15, 18, 8, 9, 11, 16, 17] + +record Node(int Id, IEnumerable? Children = null); diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/TraverseDepthFirst/TraverseDepthFirst.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TraverseDepthFirst/TraverseDepthFirst.linq new file mode 100644 index 00000000..9ee16524 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TraverseDepthFirst/TraverseDepthFirst.linq @@ -0,0 +1,40 @@ + + SuperLinq + SuperLinq + + +Node root = new(0, +[ + new(1), new(2), new(3), + new(4, + [ + new(5), new(6), + new(7, [ new(8), new(9) ]), + new(10, [ new(11) ]), + ]), + new(11), + new(12, + [ + new(13), new(14), + new(15, [ new(16), new(17) ]), + new(18), + ]), + new(19), new(20), +]); + +// Traverse a tree +var result = SuperEnumerable + .TraverseDepthFirst( + root, + static x => x.Children ?? []) + .Select(x => x.Id); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] + +record Node(int Id, IEnumerable? Children = null); diff --git a/Source/SuperLinq/Traverse.cs b/Source/SuperLinq/Traverse.cs index 74544092..682c599e 100644 --- a/Source/SuperLinq/Traverse.cs +++ b/Source/SuperLinq/Traverse.cs @@ -3,25 +3,32 @@ public partial class SuperEnumerable { /// - /// Traverses a tree in a breadth-first fashion, starting at a root - /// node and using a user-defined function to get the children at each - /// node of the tree. + /// Traverses a tree in a breadth-first fashion, starting at a root node and using a user-defined function to + /// get the children at each node of the tree. /// - /// The tree node type - /// The root of the tree to traverse. + /// + /// The tree node type + /// + /// + /// The root of the tree to traverse. + /// /// - /// The function that produces the children of each element. - /// A sequence containing the traversed values. - /// is . + /// The function that produces the children of each element. + /// + /// + /// A sequence containing the traversed values. + /// + /// + /// is . + /// /// /// - /// The tree is not checked for loops. If the resulting sequence needs - /// to be finite then it is the responsibility of - /// to ensure that loops are not - /// produced. + /// The tree is not checked for loops. If the resulting sequence needs to be finite then it is the + /// responsibility of to ensure that loops are not produced. + ///
/// - /// This function defers traversal until needed and streams the - /// results. + /// This function defers traversal until needed and streams the results. + ///
///
public static IEnumerable TraverseBreadthFirst(T root, Func> childrenSelector) { @@ -45,25 +52,32 @@ static IEnumerable Core(T root, Func> childrenSelector) } /// - /// Traverses a tree in a depth-first fashion, starting at a root node - /// and using a user-defined function to get the children at each node - /// of the tree. + /// Traverses a tree in a depth-first fashion, starting at a root node and using a user-defined function to get + /// the children at each node of the tree. /// - /// The tree node type. - /// The root of the tree to traverse. + /// + /// The tree node type. + /// + /// + /// The root of the tree to traverse. + /// /// - /// The function that produces the children of each element. - /// A sequence containing the traversed values. - /// is . + /// The function that produces the children of each element. + /// + /// + /// A sequence containing the traversed values. + /// + /// + /// is . + /// /// /// - /// The tree is not checked for loops. If the resulting sequence needs - /// to be finite then it is the responsibility of - /// to ensure that loops are not - /// produced. + /// The tree is not checked for loops. If the resulting sequence needs to be finite then it is the + /// responsibility of to ensure that loops are not produced. + ///
/// - /// This function defers traversal until needed and streams the - /// results. + /// This function defers traversal until needed and streams the results. + ///
///
public static IEnumerable TraverseDepthFirst(T root, Func> childrenSelector) { From d9f8cefbc262e20dc3847b12afa9fd6e18dcda89 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 10:26:51 -0600 Subject: [PATCH 111/124] Update documentation for `Unfold` --- Source/SuperLinq/Unfold.cs | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/Source/SuperLinq/Unfold.cs b/Source/SuperLinq/Unfold.cs index f9488bab..57dd4d4d 100644 --- a/Source/SuperLinq/Unfold.cs +++ b/Source/SuperLinq/Unfold.cs @@ -3,30 +3,39 @@ public static partial class SuperEnumerable { /// - /// Returns a sequence generated by applying a state to the generator function, - /// and from its result, determines if the sequence should have a next element, its value, - /// and the next state in the recursive call. + /// Returns a sequence generated by applying a state to the generator function, and from its result, determines + /// if the sequence should have a next element, its value, and the next state in the recursive call. /// - /// Type of state elements. - /// Type of the elements generated by the generator function. - /// The type of the elements of the result sequence. - /// The initial state. + /// + /// Type of state elements. + /// + /// + /// Type of the elements generated by the generator function. + /// + /// + /// The type of the elements of the result sequence. + /// + /// + /// The initial state. + /// /// - /// Function that takes a state and computes the next state and the next element of the sequence. + /// Function that takes a state and computes the next state and the next element of the sequence. /// /// - /// Function to determine if the unfolding should continue based the - /// result of the function. + /// Function to determine if the unfolding should continue based the result of the + /// function. /// /// - /// Function to select the state from the output of the function. + /// Function to select the state from the output of the function. /// /// - /// Function to select the result from the output of the function. + /// Function to select the result from the output of the function. /// - /// A sequence containing the results generated by the function. + /// + /// A sequence containing the results generated by the function. + /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// [Obsolete("Will be removed in v6.0.0; better implemented as `SuperEnumerable.Generate().TakeWhile().Select()`")] public static IEnumerable Unfold( From ef004c60e0d3235b711f149e62f22aad119ee4d4 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 10:41:57 -0600 Subject: [PATCH 112/124] Update documentation for `TrySingle` --- .../SuperLinq.SuperEnumerable.TrySingle.md | 13 +++ .../SuperLinq/TrySingle/TrySingle1.linq | 19 ++++ .../SuperLinq/TrySingle/TrySingle2.linq | 19 ++++ Source/SuperLinq/TrySingle.cs | 106 +++++++++--------- 4 files changed, 107 insertions(+), 50 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TrySingle.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/TrySingle/TrySingle1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/TrySingle/TrySingle2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TrySingle.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TrySingle.md new file mode 100644 index 00000000..0507e9d8 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.TrySingle.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.TrySingle``2(System.Collections.Generic.IEnumerable{``0},``1,``1,``1) +example: [*content] +--- +The following code example demonstrates how to evaluate the cardinality of a sequence using `TrySingle`. +[!code-csharp[](SuperLinq/TrySingle/TrySingle1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.TrySingle``3(System.Collections.Generic.IEnumerable{``0},``1,``1,``1,System.Func{``1,``0,``2}) +example: [*content] +--- +The following code example demonstrates how to evaluate the cardinality of a sequence using `TrySingle`. +[!code-csharp[](SuperLinq/TrySingle/TrySingle2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/TrySingle/TrySingle1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TrySingle/TrySingle1.linq new file mode 100644 index 00000000..0dcd1acc --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TrySingle/TrySingle1.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +// Determine cardinality of sequence +var result = Enumerable.Range(1, 0).TrySingle("none", "one", "many"); +Console.WriteLine(result.ToString()); + +result = Enumerable.Range(1, 1).TrySingle("none", "one", "many"); +Console.WriteLine(result.ToString()); + +result = Enumerable.Range(1, 10).TrySingle("none", "one", "many"); +Console.WriteLine(result.ToString()); + +// This code produces the following output: +// (none, 0) +// (one, 1) +// (many, 0) diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/TrySingle/TrySingle2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TrySingle/TrySingle2.linq new file mode 100644 index 00000000..4501893d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TrySingle/TrySingle2.linq @@ -0,0 +1,19 @@ + + SuperLinq + SuperLinq + + +// Determine cardinality of sequence +var result = Enumerable.Range(10, 0).TrySingle(0, 1, 2, (count, one) => count switch { 0 => "no elements", 1 => $"single({one})", 2 => "many elements" }); +Console.WriteLine(result); + +result = Enumerable.Range(10, 1).TrySingle(0, 1, 2, (count, one) => count switch { 0 => "no elements", 1 => $"single({one})", 2 => "many elements" }); +Console.WriteLine(result); + +result = Enumerable.Range(10, 10).TrySingle(0, 1, 2, (count, one) => count switch { 0 => "no elements", 1 => $"single({one})", 2 => "many elements" }); +Console.WriteLine(result); + +// This code produces the following output: +// no elements +// single(10) +// many elements diff --git a/Source/SuperLinq/TrySingle.cs b/Source/SuperLinq/TrySingle.cs index 03222bdb..59d0bed0 100644 --- a/Source/SuperLinq/TrySingle.cs +++ b/Source/SuperLinq/TrySingle.cs @@ -3,32 +3,36 @@ public static partial class SuperEnumerable { /// - /// Returns a tuple with the cardinality of the sequence and the - /// single element in the sequence if it contains exactly one element. - /// similar to . + /// Returns a tuple with the cardinality of the sequence and the single element in the sequence if it contains + /// exactly one element. similar to . /// - /// The source sequence. + /// + /// The type of the elements of . + /// + /// + /// The type that expresses cardinality. + /// + /// + /// The source sequence. + /// /// - /// The value that is returned in the tuple if the sequence has zero - /// elements. + /// The value that is returned in the tuple if the sequence has zero elements. + /// /// - /// The value that is returned in the tuple if the sequence has a - /// single element only. + /// The value that is returned in the tuple if the sequence has a single element only. + /// /// - /// The value that is returned in the tuple if the sequence has two or - /// more elements. - /// - /// The type of the elements of . - /// - /// The type that expresses cardinality. + /// The value that is returned in the tuple if the sequence has two or more elements. + /// /// - /// A tuple containing the identified - /// and either the single value of in the sequence - /// or its default value. - /// is null + /// A tuple containing the identified and either the single value of + /// in the sequence or its default value. + /// + /// + /// is . + /// /// - /// This operator uses immediate execution, but never consumes more - /// than two elements from the sequence. + /// This operator uses immediate execution, but never consumes more than two elements from the sequence. /// public static (TCardinality Cardinality, T? Value) TrySingle(this IEnumerable source, @@ -38,45 +42,47 @@ public static (TCardinality Cardinality, T? Value) } /// - /// Returns a result projected from the the cardinality of the sequence - /// and the single element in the sequence if it contains exactly one - /// element. + /// Returns a result projected from the the cardinality of the sequence and the single element in the sequence + /// if it contains exactly one element. /// - /// The source sequence. + /// + /// The type of the elements of . + /// + /// + /// The type that expresses cardinality. + /// + /// + /// The type of the result value returned by the function. + /// + /// + /// The source sequence. + /// /// - /// The value that is passed as the first argument to - /// if the sequence has zero - /// elements. + /// The value that is passed as the first argument to if the sequence has + /// zero elements. + /// /// - /// The value that is passed as the first argument to - /// if the sequence has a - /// single element only. + /// The value that is passed as the first argument to if the sequence has a + /// single element only. + /// /// - /// The value that is passed as the first argument to - /// if the sequence has two or - /// more elements. + /// The value that is passed as the first argument to if the sequence has two + /// or more elements. + /// /// - /// A function that receives the cardinality and, if the - /// sequence has just one element, the value of that element as - /// argument and projects a resulting value of type - /// . - /// - /// The type of the elements of . - /// - /// The type that expresses cardinality. - /// - /// The type of the result value returned by the - /// function. + /// A function that receives the cardinality and, if the sequence has just one element, the value of that + /// element as argument and projects a resulting value of type + /// . + /// /// - /// The value returned by . + /// The value returned by . /// - /// is null - /// is null + /// + /// or is . + /// /// - /// This operator uses immediate execution, but never consumes more - /// than two elements from the sequence. + /// This operator uses immediate execution, but never consumes more than two elements from the sequence. /// - public static TResult TrySingle( this IEnumerable source, TCardinality zero, TCardinality one, TCardinality many, From b373f485b733677a072f93bd76af0fa3a0a98f39 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 11:46:30 -0600 Subject: [PATCH 113/124] fix comment --- Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeUntil/TakeUntil.linq | 2 +- .../apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex1.linq | 2 +- .../apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex2.linq | 2 +- .../apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex3.linq | 2 +- .../apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex4.linq | 2 +- .../apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex5.linq | 2 +- .../apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex6.linq | 2 +- Docs/SuperLinq.Docs/apidoc/SuperLinq/Transpose/Transpose.linq | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeUntil/TakeUntil.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeUntil/TakeUntil.linq index bfcec15f..f5f04701 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeUntil/TakeUntil.linq +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/TakeUntil/TakeUntil.linq @@ -14,5 +14,5 @@ Console.WriteLine( string.Join(", ", result) + "]"); -// One possible random output is as follows: +// This code produces the following output: // [1, 2, 3, 4, 5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex1.linq index b4a73659..0bc33370 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex1.linq +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex1.linq @@ -14,5 +14,5 @@ Console.WriteLine( string.Join(", ", result) + "]"); -// One possible random output is as follows: +// This code produces the following output: // [alp, bar, car, , , foo] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex2.linq index f9c38a94..ee7afc0c 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex2.linq +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex2.linq @@ -14,5 +14,5 @@ Console.WriteLine( string.Join(", ", result) + "]"); -// One possible random output is as follows: +// This code produces the following output: // [alp, bar, car, , , foo, , , , , , , , , , , , , , , , , , , , ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex3.linq index 167336f1..c5048738 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex3.linq +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex3.linq @@ -14,5 +14,5 @@ Console.WriteLine( string.Join(", ", result) + "]"); -// One possible random output is as follows: +// This code produces the following output: // [0:alp, 1:bar, 2:car, , , 5:foo] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex4.linq index 08cb112e..1b75e6cf 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex4.linq +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex4.linq @@ -14,5 +14,5 @@ Console.WriteLine( string.Join(", ", result) + "]"); -// One possible random output is as follows: +// This code produces the following output: // [0:alp, 1:bar, 2:car, , , 5:foo] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex5.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex5.linq index d410c830..72c94763 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex5.linq +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex5.linq @@ -14,5 +14,5 @@ Console.WriteLine( string.Join(", ", result) + "]"); -// One possible random output is as follows: +// This code produces the following output: // [0:alp, 1:bar, 2:car, , , 5:foo, , , , , , , , , , , , , , , , , , , , ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex6.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex6.linq index d8bbced1..42091d55 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex6.linq +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ToArrayByIndex/ToArrayByIndex6.linq @@ -14,5 +14,5 @@ Console.WriteLine( string.Join(", ", result) + "]"); -// One possible random output is as follows: +// This code produces the following output: // [0:alp, 1:bar, 2:car, , , 5:foo, , , , , , , , , , , , , , , , , , , , ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Transpose/Transpose.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Transpose/Transpose.linq index aae88948..8b546c1b 100644 --- a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Transpose/Transpose.linq +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Transpose/Transpose.linq @@ -20,7 +20,7 @@ Console.WriteLine( result.Select(c => " [" + string.Join(", ", c) + "]")) + Environment.NewLine + "]"); -// One possible random output is as follows: +// This code produces the following output: // [ // [10, 20, 30], // [11, 31], From ba4471ae883d4809be27098540b85ea9efe5f492 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 11:46:44 -0600 Subject: [PATCH 114/124] Update documentation for `Using` --- .../apidoc/SuperLinq.SuperEnumerable.Using.md | 6 +++ .../apidoc/SuperLinq/Using/Using.linq | 45 +++++++++++++++++++ Source/SuperLinq/Using.cs | 41 ++++++++++------- 3 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Using.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Using/Using.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Using.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Using.md new file mode 100644 index 00000000..f1e4b2ad --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Using.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Using``2(System.Func{``1},System.Func{``1,System.Collections.Generic.IEnumerable{``0}}) +example: [*content] +--- +The following code example demonstrates how to create a sequence that throws on enumeration using `Using`. +[!code-csharp[](SuperLinq/Using/Using.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Using/Using.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Using/Using.linq new file mode 100644 index 00000000..7133c901 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Using/Using.linq @@ -0,0 +1,45 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Hold a resource for the duration of an enumeration +var result = SuperEnumerable + .Using( + () => new DummyDisposable(), + d => d.GetValues()) + .Do(x => Console.Write($"{x}, ")); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// Constructor +// GetValues +// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, +// Dispose +// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + +class DummyDisposable : IDisposable +{ + public DummyDisposable() + { + Console.WriteLine("Constructor"); + } + + public IEnumerable GetValues() + { + Console.WriteLine("GetValues"); + return Enumerable.Range(1, 10); + } + + public void Dispose() + { + Console.WriteLine(); + Console.WriteLine("Dispose"); + } +} diff --git a/Source/SuperLinq/Using.cs b/Source/SuperLinq/Using.cs index 363ee8c1..9199f95f 100644 --- a/Source/SuperLinq/Using.cs +++ b/Source/SuperLinq/Using.cs @@ -3,26 +3,37 @@ public static partial class SuperEnumerable { /// - /// Generates a sequence that's dependent on a resource object whose lifetime is determined by the sequence usage - /// duration. + /// Generates a sequence that's dependent on a resource object whose lifetime is determined by the sequence + /// usage duration. /// - /// Source element type. - /// Resource type. - /// Resource factory function. - /// Enumerable factory function, having access to the obtained resource. - /// Sequence whose use controls the lifetime of the associated obtained resource. - /// or is . + /// + /// Source element type. + /// + /// + /// Resource type. + /// + /// + /// Resource factory function. + /// + /// + /// Enumerable factory function, having access to the obtained resource. + /// + /// + /// Sequence whose use controls the lifetime of the associated obtained resource. + /// + /// + /// or is . + /// /// /// - /// and are evaluated lazily, once - /// enumeration has begun. The value returned by will be disposed after the - /// enumeration has completed. + /// and are evaluated lazily, once + /// enumeration has begun. The value returned by will be disposed after the + /// enumeration has completed. /// /// - /// The values returned by and are not - /// cached; multiple iterations of the returned by this method will call these methods - /// separately for each iteration. + /// The values returned by and are not + /// cached; multiple iterations of the returned by this method will call these + /// methods separately for each iteration. /// /// public static IEnumerable Using( From e232e4df1958357a6e8a271667013b8d5768faf2 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 12:14:55 -0600 Subject: [PATCH 115/124] Update documentation for `Where` --- .../apidoc/SuperLinq.SuperEnumerable.Where.md | 6 +++++ .../apidoc/SuperLinq/Where/Where.linq | 18 ++++++++++++++ Source/SuperLinq/Where.cs | 24 ++++++++++++------- 3 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Where.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Where/Where.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Where.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Where.md new file mode 100644 index 00000000..e93ebafd --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Where.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.Where``1(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to create filter a sequence with matching `bool` values using `Where`. +[!code-csharp[](SuperLinq/Where/Where.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Where/Where.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Where/Where.linq new file mode 100644 index 00000000..49157651 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Where/Where.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 5); + +// Filter a sequence based on a matching sequence of bools +var result = sequence + .Where([true, false, true, true, false]); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 3, 4] diff --git a/Source/SuperLinq/Where.cs b/Source/SuperLinq/Where.cs index c356c30d..4977df24 100644 --- a/Source/SuperLinq/Where.cs +++ b/Source/SuperLinq/Where.cs @@ -3,17 +3,25 @@ public static partial class SuperEnumerable { /// - /// Filters a sequence of values based on an enumeration of boolean values + /// Filters a sequence of values based on an enumeration of boolean values /// - /// The type of the elements of source. - /// An to filter. - /// An of boolean values identifying which elements of to keep. + /// + /// The type of the elements of source. + /// + /// + /// An to filter. + /// + /// + /// An of boolean values identifying which elements of to + /// keep. + /// /// - /// An that contains elements from the input sequence - /// where the matching value in is . + /// An that contains elements from the input sequence where the matching value in + /// is . /// - /// is . - /// is . + /// + /// or is . + /// public static IEnumerable Where(this IEnumerable source, IEnumerable filter) { Guard.IsNotNull(source); From 38c723f9e500314de47a77585107722b8012aab1 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 12:22:19 -0600 Subject: [PATCH 116/124] Update documentation for `While` --- .../apidoc/SuperLinq.SuperEnumerable.While.md | 6 ++++ .../apidoc/SuperLinq/While/While.linq | 21 ++++++++++++ Source/SuperLinq/While.cs | 32 ++++++++++++------- 3 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.While.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/While/While.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.While.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.While.md new file mode 100644 index 00000000..63d7a38e --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.While.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.While``1(System.Func{System.Boolean},System.Collections.Generic.IEnumerable{``0}) +example: [*content] +--- +The following code example demonstrates how to repeat a sequence while a condition is true using `While`. +[!code-csharp[](SuperLinq/While/While.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/While/While.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/While/While.linq new file mode 100644 index 00000000..5f9f0613 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/While/While.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 2); + +// Repeat a sequence while a condition is true +var count = 0; +var result = SuperEnumerable + .While( + () => count++ < 3, + sequence); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 1, 2, 1, 2] diff --git a/Source/SuperLinq/While.cs b/Source/SuperLinq/While.cs index b0a75fdd..59f4cce5 100644 --- a/Source/SuperLinq/While.cs +++ b/Source/SuperLinq/While.cs @@ -3,22 +3,32 @@ public static partial class SuperEnumerable { /// - /// Generates an enumerable sequence by repeating a source sequence as long as the given loop condition holds. + /// Generates an enumerable sequence by repeating a source sequence as long as the given loop condition holds. /// - /// Source sequence element type. - /// Loop condition. - /// Sequence to repeat while the condition evaluates true. - /// Sequence generated by repeating the given sequence while the condition evaluates to true. - /// or is . + /// + /// Source sequence element type. + /// + /// + /// Loop condition. + /// + /// + /// Sequence to repeat while the condition evaluates true. + /// + /// + /// Sequence generated by repeating the given sequence while the condition evaluates to true. + /// + /// + /// or is . + /// /// /// - /// is evaluated lazily, once at the start of each loop of . + /// is evaluated lazily, once at the start of each loop of . /// /// - /// is cached via , so that it - /// is only iterated once during the first loop. Successive loops will enumerate the cache instead of . + /// is cached via , so that + /// it is only iterated once during the first loop. Successive loops will enumerate the cache instead of + /// . /// /// public static IEnumerable While(Func condition, IEnumerable source) From b9089429e2de276dc8df7a29eec28d833f20d54f Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 12:31:44 -0600 Subject: [PATCH 117/124] Update documentation for `WhereLag` --- .../SuperLinq.SuperEnumerable.WhereLag.md | 13 +++ .../apidoc/SuperLinq/WhereLag/WhereLag1.linq | 18 +++++ .../apidoc/SuperLinq/WhereLag/WhereLag2.linq | 18 +++++ Source/SuperLinq/WhereLag.cs | 80 ++++++++++++------- 4 files changed, 100 insertions(+), 29 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WhereLag.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLag/WhereLag1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLag/WhereLag2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WhereLag.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WhereLag.md new file mode 100644 index 00000000..75e79fdb --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WhereLag.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.WhereLag``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to filter a sequence based on a lagging value in the sequence using `WhereLag`. +[!code-csharp[](SuperLinq/WhereLag/WhereLag1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.WhereLag``1(System.Collections.Generic.IEnumerable{``0},System.Int32,``0,System.Func{``0,``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to filter a sequence based on a lagging value in the sequence using `WhereLag`. +[!code-csharp[](SuperLinq/WhereLag/WhereLag2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLag/WhereLag1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLag/WhereLag1.linq new file mode 100644 index 00000000..0f447673 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLag/WhereLag1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Filter a sequence based on a leading value +var result = sequence + .WhereLag(1, (cur, lag) => cur + lag < 10); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [1, 2, 3, 4, 5] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLag/WhereLag2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLag/WhereLag2.linq new file mode 100644 index 00000000..9ed117b0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLag/WhereLag2.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Filter a sequence based on a leading value +var result = sequence + .WhereLag(1, 20, (cur, lag) => cur + lag < 10); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [2, 3, 4, 5] diff --git a/Source/SuperLinq/WhereLag.cs b/Source/SuperLinq/WhereLag.cs index b6b04977..3fd77c70 100644 --- a/Source/SuperLinq/WhereLag.cs +++ b/Source/SuperLinq/WhereLag.cs @@ -3,26 +3,36 @@ public static partial class SuperEnumerable { /// - /// Filters a sequence of values based on a predicate evaluated on the current value and a lagging value. + /// Filters a sequence of values based on a predicate evaluated on the current value and a lagging value. /// - /// The type of the elements in the source sequence. - /// An to filter. - /// The offset (expressed as a positive number) by which to lag each element of the - /// sequence. - /// A function which accepts the current and lagged element (in that order) to - /// test for a condition. - /// An that contains elements from the input sequence that satisfy the - /// condition. - /// is . - /// is . - /// is below 1. + /// + /// The type of the elements in the source sequence. + /// + /// + /// An to filter. + /// + /// + /// The offset (expressed as a positive number) by which to lag each element of the sequence. + /// + /// + /// A function which accepts the current and lagged element (in that order) to test for a condition. + /// + /// + /// An that contains elements from the input sequence that satisfy the condition. + /// + /// + /// or is . + /// + /// + /// is below 1. + /// /// /// - /// For elements of the sequence that are less than items from the end, (?) is used as the Lag value. + /// For elements of the sequence that are less than items from the end, (?) is used as the Lag value. /// /// - /// This operator evaluates in a deferred and streaming manner. + /// This operator evaluates in a deferred and streaming manner. /// /// public static IEnumerable WhereLag(this IEnumerable source, int offset, Func predicate) @@ -31,23 +41,35 @@ public static IEnumerable WhereLag(this IEnumerable s } /// - /// Filters a sequence of values based on a predicate evaluated on the current value and a lagging value. + /// Filters a sequence of values based on a predicate evaluated on the current value and a lagging value. /// - /// The type of the elements in the source sequence. - /// An to filter. - /// The offset (expressed as a positive number) by which to lag each element of the - /// sequence. - /// A default value supplied for the lagged element when none is available - /// A function which accepts the current and lagged element (in that order) to - /// test for a condition. - /// An that contains elements from the input sequence that satisfy the - /// condition. - /// is . - /// is . - /// is below 1. + /// + /// The type of the elements in the source sequence. + /// + /// + /// An to filter. + /// + /// + /// The offset (expressed as a positive number) by which to lag each element of the sequence. + /// + /// + /// A default value supplied for the lagged element when none is available + /// + /// + /// A function which accepts the current and lagged element (in that order) to test for a condition. + /// + /// + /// An that contains elements from the input sequence that satisfy the condition. + /// + /// + /// or is . + /// + /// + /// is below 1. + /// /// /// - /// This operator evaluates in a deferred and streaming manner. + /// This operator evaluates in a deferred and streaming manner. /// /// public static IEnumerable WhereLag(this IEnumerable source, int offset, TSource defaultLagValue, Func predicate) From 53ea5ed88d132166e0965982bbdd673d9aed3b9d Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 12:32:00 -0600 Subject: [PATCH 118/124] Update documentation for `WhereLead` --- .../SuperLinq.SuperEnumerable.WhereLead.md | 13 ++++ .../SuperLinq/WhereLead/WhereLead1.linq | 18 +++++ .../SuperLinq/WhereLead/WhereLead2.linq | 18 +++++ Source/SuperLinq/WhereLead.cs | 78 ++++++++++++------- 4 files changed, 98 insertions(+), 29 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WhereLead.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLead/WhereLead1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLead/WhereLead2.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WhereLead.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WhereLead.md new file mode 100644 index 00000000..bc81a53f --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WhereLead.md @@ -0,0 +1,13 @@ +--- +uid: SuperLinq.SuperEnumerable.WhereLead``1(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{``0,``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to filter a sequence based on a leading value in the sequence using `WhereLead`. +[!code-csharp[](SuperLinq/WhereLead/WhereLead1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.WhereLead``1(System.Collections.Generic.IEnumerable{``0},System.Int32,``0,System.Func{``0,``0,System.Boolean}) +example: [*content] +--- +The following code example demonstrates how to filter a sequence based on a leading value in the sequence using `WhereLead`. +[!code-csharp[](SuperLinq/WhereLead/WhereLead2.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLead/WhereLead1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLead/WhereLead1.linq new file mode 100644 index 00000000..7445d4ac --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLead/WhereLead1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Filter a sequence based on a leading value +var result = sequence + .WhereLead(1, (cur, lead) => cur + lead >= 10); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [5, 6, 7, 8, 9, 10] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLead/WhereLead2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLead/WhereLead2.linq new file mode 100644 index 00000000..fb901057 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WhereLead/WhereLead2.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Filter a sequence based on a leading value +var result = sequence + .WhereLead(1, -20, (cur, lead) => cur + lead >= 10); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [5, 6, 7, 8, 9] diff --git a/Source/SuperLinq/WhereLead.cs b/Source/SuperLinq/WhereLead.cs index 6182bb79..0506a660 100644 --- a/Source/SuperLinq/WhereLead.cs +++ b/Source/SuperLinq/WhereLead.cs @@ -3,26 +3,35 @@ public static partial class SuperEnumerable { /// - /// Filters a sequence of values based on a predicate evaluated on the current value and a leading value. + /// Filters a sequence of values based on a predicate evaluated on the current value and a leading value. /// - /// The type of the elements in the source sequence. - /// The sequence over which to evaluate Lead. - /// The offset (expressed as a positive number) by which to lead each element of the - /// sequence. - /// A function which accepts the current and subsequent (lead) element (in that order) to - /// test for a condition. - /// An that contains elements from the input sequence that satisfy the - /// condition. - /// is . - /// is . - /// is below 1. + /// + /// The type of the elements in the source sequence. + /// + /// + /// The sequence over which to evaluate Lead. + /// + /// + /// The offset (expressed as a positive number) by which to lead each element of the sequence. + /// + /// + /// A function which accepts the current and subsequent (lead) element (in that order) to test for a condition. + /// + /// + /// An that contains elements from the input sequence that satisfy the condition. + /// + /// + /// or is . + /// + /// + /// is below 1. /// /// - /// For elements of the sequence that are less than items from the end, (?) is used as the lead value. + /// For elements of the sequence that are less than items from the end, (?) is used as the lead value. /// /// - /// This operator evaluates in a deferred and streaming manner. + /// This operator evaluates in a deferred and streaming manner. /// /// public static IEnumerable WhereLead(this IEnumerable source, int offset, Func predicate) @@ -31,23 +40,34 @@ public static IEnumerable WhereLead(this IEnumerable } /// - /// Filters a sequence of values based on a predicate evaluated on the current value and a leading value. + /// Filters a sequence of values based on a predicate evaluated on the current value and a leading value. /// - /// The type of the elements in the source sequence. - /// The sequence over which to evaluate Lead. - /// The offset (expressed as a positive number) by which to lead each element of the - /// sequence. - /// A default value supplied for the leading element when none is available - /// A function which accepts the current and subsequent (lead) element (in that order) to - /// test for a condition. - /// An that contains elements from the input sequence that satisfy the - /// condition. - /// is . - /// is . - /// is below 1. + /// + /// The type of the elements in the source sequence. + /// + /// + /// The sequence over which to evaluate Lead. + /// + /// + /// The offset (expressed as a positive number) by which to lead each element of the sequence. + /// + /// + /// A default value supplied for the leading element when none is available + /// + /// + /// A function which accepts the current and subsequent (lead) element (in that order) to test for a condition. + /// + /// + /// An that contains elements from the input sequence that satisfy the condition. + /// + /// + /// or is . + /// + /// + /// is below 1. /// /// - /// This operator evaluates in a deferred and streaming manner. + /// This operator evaluates in a deferred and streaming manner. /// /// public static IEnumerable WhereLead(this IEnumerable source, int offset, TSource defaultLeadValue, Func predicate) From da5f31b153a356633b234db4026687bff28ed599 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 12:52:23 -0600 Subject: [PATCH 119/124] Update documentation for `ZipMap` --- .../SuperLinq.SuperEnumerable.ZipMap.md | 6 ++++ .../apidoc/SuperLinq/ZipMap/ZipMap.linq | 18 ++++++++++ Source/SuperLinq/ZipMap.cs | 35 +++++++++++++------ 3 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipMap.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipMap/ZipMap.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipMap.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipMap.md new file mode 100644 index 00000000..0335a16b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipMap.md @@ -0,0 +1,6 @@ +--- +uid: SuperLinq.SuperEnumerable.ZipMap``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1}) +example: [*content] +--- +The following code example demonstrates how to generate a sequence of values and a projection of that value using `ZipMap`. +[!code-csharp[](SuperLinq/ZipMap/ZipMap.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipMap/ZipMap.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipMap/ZipMap.linq new file mode 100644 index 00000000..a109788b --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipMap/ZipMap.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var sequence = new[] { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", }; + +// Filter a sequence based on a leading value +var result = sequence + .ZipMap(x => x.ToString().Length); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(one, 3), (two, 3), (three, 5), (four, 4), (five, 4), (six, 3), (seven, 5), (eight, 5), (nine, 4), (ten, 3)] diff --git a/Source/SuperLinq/ZipMap.cs b/Source/SuperLinq/ZipMap.cs index 5f8098e1..60194b13 100644 --- a/Source/SuperLinq/ZipMap.cs +++ b/Source/SuperLinq/ZipMap.cs @@ -3,20 +3,33 @@ public static partial class SuperEnumerable { /// - /// Applies a function to each element in a sequence - /// and returns a sequence of tuples containing both - /// the original item as well as the function result. + /// Applies a function to each element in a sequence and returns a sequence of tuples containing both the + /// original item as well as the function result. /// - /// The type of the elements of source - /// The type of the value returned by selector - /// A sequence of values to invoke a transform function on - /// A transform function to apply to each source element + /// + /// The type of the elements of source + /// + /// + /// The type of the value returned by selector + /// + /// + /// A sequence of values to invoke a transform function on + /// + /// + /// A transform function to apply to each source element + /// /// - /// An whose elements are a tuple of the original element and - /// the item returned from calling the on that element. + /// An whose elements are a tuple of the original element and the item returned + /// from calling the on that element. /// - /// is . - /// is . + /// + /// or is . + /// + /// + /// + /// This operator uses deferred execution and streams its results. + /// + /// public static IEnumerable<(TSource item, TResult result)> ZipMap(this IEnumerable source, Func selector) { Guard.IsNotNull(source); From 3fbe339e5f88bf224315c53b468c004eb5e4c4a2 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 13:16:25 -0600 Subject: [PATCH 120/124] Update documentation for `ZipLongest` --- .../SuperLinq.SuperEnumerable.ZipLongest.md | 42 +++ .../SuperLinq/ZipLongest/ZipLongest1.linq | 18 ++ .../SuperLinq/ZipLongest/ZipLongest2.linq | 21 ++ .../SuperLinq/ZipLongest/ZipLongest3.linq | 22 ++ .../SuperLinq/ZipLongest/ZipLongest4.linq | 23 ++ .../SuperLinq/ZipLongest/ZipLongest5.linq | 24 ++ .../SuperLinq/ZipLongest/ZipLongest6.linq | 31 ++ .../SuperLinq.Generator/ZipLongest.sbntxt | 75 +++-- .../ZipLongest.g.cs | 285 ++++++++++++------ 9 files changed, 411 insertions(+), 130 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipLongest.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest5.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest6.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipLongest.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipLongest.md new file mode 100644 index 00000000..58a7a682 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipLongest.md @@ -0,0 +1,42 @@ +--- +uid: SuperLinq.SuperEnumerable.ZipLongest``2(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipLongest` to merge two sequences. +[!code-csharp[](SuperLinq/ZipLongest/ZipLongest1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ZipLongest``3(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipLongest` to merge two sequences. +[!code-csharp[](SuperLinq/ZipLongest/ZipLongest3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ZipLongest``3(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Func{``0,``1,``2}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipLongest` to merge three sequences. +[!code-csharp[](SuperLinq/ZipLongest/ZipLongest2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ZipLongest``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipLongest` to merge three sequences. +[!code-csharp[](SuperLinq/ZipLongest/ZipLongest5.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ZipLongest``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Func{``0,``1,``2,``3}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipLongest` to merge four sequences. +[!code-csharp[](SuperLinq/ZipLongest/ZipLongest4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ZipLongest``5(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Func{``0,``1,``2,``3,``4}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipLongest` to merge four sequences. +[!code-csharp[](SuperLinq/ZipLongest/ZipLongest6.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest1.linq new file mode 100644 index 00000000..d1449e94 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, 4, 5 }; + +// Zip two sequences together +var result = seq1.ZipLongest(seq2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(aaa, 1), (bb, 2), (c, 3), (ddd, 4), (, 5)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest2.linq new file mode 100644 index 00000000..3ad6610f --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest2.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, 4, 5 }; + +// Zip two sequences together +var result = seq1 + .ZipLongest( + seq2, + (a, b) => new { A = a, B = b, }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ A = aaa, B = 1 }, { A = bb, B = 2 }, { A = c, B = 3 }, { A = ddd, B = 4 }, { A = , B = 5 }] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest3.linq new file mode 100644 index 00000000..4d16c03c --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest3.linq @@ -0,0 +1,22 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", }; +var seq2 = new[] { 1, 2, 3, 4, }; +var seq3 = new[] { 20, 5, 7, 12, 42 }; + +// Zip three sequences together +var result = seq1 + .ZipLongest( + seq2, + seq3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(aaa, 1, 20), (bb, 2, 5), (c, 3, 7), (, 4, 12), (, 0, 42)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest4.linq new file mode 100644 index 00000000..6dbb3d4d --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest4.linq @@ -0,0 +1,23 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", }; +var seq2 = new[] { 1, 2, 3, 4, }; +var seq3 = new[] { 20, 5, 7, 12, 42 }; + +// Zip three sequences together +var result = seq1 + .ZipLongest( + seq2, + seq3, + (a, b, c) => new { A = a, B = b, C = c, }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ A = aaa, B = 1, C = 20 }, { A = bb, B = 2, C = 5 }, { A = c, B = 3, C = 7 }, { A = , B = 4, C = 12 }, { A = , B = 0, C = 42 }] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest5.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest5.linq new file mode 100644 index 00000000..8c1afaf8 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest5.linq @@ -0,0 +1,24 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, }; +var seq3 = new[] { 20, 5, }; +var seq4 = new[] { "zz", }; + +// Zip four sequences together +var result = seq1 + .ZipLongest( + seq2, + seq3, + seq4); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(aaa, 1, 20, zz), (bb, 2, 5, ), (c, 3, 0, ), (ddd, 0, 0, )] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest6.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest6.linq new file mode 100644 index 00000000..6f86c40c --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipLongest/ZipLongest6.linq @@ -0,0 +1,31 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, }; +var seq3 = new[] { 20, 5, }; +var seq4 = new[] { "zz", }; + +// Zip four sequences together +var result = seq1 + .ZipLongest( + seq2, + seq3, + seq4, + (a, b, c, d) => new + { + A = a, + B = b, + C = c, + D = d, + }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ A = aaa, B = 1, C = 20, D = zz }, { A = bb, B = 2, C = 5, D = }, { A = c, B = 3, C = 0, D = }, { A = ddd, B = 0, C = 0, D = }] diff --git a/Generators/SuperLinq.Generator/ZipLongest.sbntxt b/Generators/SuperLinq.Generator/ZipLongest.sbntxt index 8c4a264e..d4311b24 100644 --- a/Generators/SuperLinq.Generator/ZipLongest.sbntxt +++ b/Generators/SuperLinq.Generator/ZipLongest.sbntxt @@ -24,24 +24,32 @@ public static partial class SuperEnumerable {{~ for $i in 2..4 ~}} /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. /// - /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . - /// - /// This method uses deferred execution and streams its results. - /// - /// or any of the input sequences is null. + /// + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// + /// + /// This method uses deferred execution and streams its results. + /// + /// + /// or any of the input sequences is . + /// {{~ for $j in 1..$i ~}} - /// The type of the elements of . - /// The {{ $ordinals[$j] }} sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The {{ $ordinals[$j] }} sequence of elements. + /// {{~ end ~}} public static global::System.Collections.Generic.IEnumerable ZipLongest<{{ for $j in 1..$i }}T{{ $j }}, {{ end }}TResult>(this {{~ for $j in 1..$i ~}} @@ -101,22 +109,27 @@ public static partial class SuperEnumerable } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. - /// - /// This method uses deferred execution and streams its results. - /// - /// Any of the input sequences is null. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. + /// + /// + /// A sequence of containing corresponding elements from each + /// of the sequences. + /// + /// + /// This method uses deferred execution and streams its results. + /// + /// + /// Any of the input sequences is . + /// {{~ for $j in 1..$i ~}} - /// The type of the elements of . - /// The {{ $ordinals[$j] }} sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The {{ $ordinals[$j] }} sequence of elements. + /// {{~ end ~}} public static global::System.Collections.Generic.IEnumerable<({{~ for $j in 1..$i ~}}T{{ $j }}?{{ if !for.last }},{{ end }}{{ end }})> ZipLongest<{{~ for $j in 1..$i ~}}T{{ $j }}{{ if !for.last }},{{ end }}{{ end }}>(this diff --git a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ZipLongest.g.cs b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ZipLongest.g.cs index 2a67b46b..0f9b084d 100644 --- a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ZipLongest.g.cs +++ b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ZipLongest.g.cs @@ -15,25 +15,37 @@ private static bool DoRead(bool flag, IEnumerator iter, out T? value) } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable ZipLongest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -59,23 +71,32 @@ private static bool DoRead(bool flag, IEnumerator iter, out T? value) } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. + /// + /// A sequence of containing corresponding elements from each + /// of the sequences. + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(T1? , T2? )> ZipLongest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second) => ZipLongest(first, second, global::System.ValueTuple.Create); private sealed class ZipLongestIterator : ListIterator { @@ -108,27 +129,43 @@ protected override TResult ElementAt(int index) } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable ZipLongest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -157,25 +194,38 @@ protected override TResult ElementAt(int index) } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. + /// + /// A sequence of containing corresponding elements from each + /// of the sequences. + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(T1? , T2? , T3? )> ZipLongest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third) => ZipLongest(first, second, third, global::System.ValueTuple.Create); private sealed class ZipLongestIterator : ListIterator { @@ -210,29 +260,49 @@ protected override TResult ElementAt(int index) } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable ZipLongest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -264,27 +334,44 @@ protected override TResult ElementAt(int index) } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. + /// + /// A sequence of containing corresponding elements from each + /// of the sequences. + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(T1? , T2? , T3? , T4? )> ZipLongest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth) => ZipLongest(first, second, third, fourth, global::System.ValueTuple.Create); private sealed class ZipLongestIterator : ListIterator { From b0e597c4619bfdd55fe3811e698a089df003a37b Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 13:16:42 -0600 Subject: [PATCH 121/124] Update documentation for `ZipShortest` --- .../SuperLinq.SuperEnumerable.ZipShortest.md | 42 +++ .../SuperLinq/ZipShortest/ZipShortest1.linq | 18 ++ .../SuperLinq/ZipShortest/ZipShortest2.linq | 21 ++ .../SuperLinq/ZipShortest/ZipShortest3.linq | 22 ++ .../SuperLinq/ZipShortest/ZipShortest4.linq | 23 ++ .../SuperLinq/ZipShortest/ZipShortest5.linq | 24 ++ .../SuperLinq/ZipShortest/ZipShortest6.linq | 31 ++ .../SuperLinq.Generator/ZipShortest.sbntxt | 64 ++-- .../ZipShortest.g.cs | 276 ++++++++++++------ 9 files changed, 403 insertions(+), 118 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipShortest.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest4.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest5.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest6.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipShortest.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipShortest.md new file mode 100644 index 00000000..1d544019 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.ZipShortest.md @@ -0,0 +1,42 @@ +--- +uid: SuperLinq.SuperEnumerable.ZipShortest``2(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipShortest` to merge two sequences. +[!code-csharp[](SuperLinq/ZipShortest/ZipShortest1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ZipShortest``3(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipShortest` to merge two sequences. +[!code-csharp[](SuperLinq/ZipShortest/ZipShortest3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ZipShortest``3(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Func{``0,``1,``2}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipShortest` to merge three sequences. +[!code-csharp[](SuperLinq/ZipShortest/ZipShortest2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ZipShortest``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipShortest` to merge three sequences. +[!code-csharp[](SuperLinq/ZipShortest/ZipShortest5.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ZipShortest``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Func{``0,``1,``2,``3}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipShortest` to merge four sequences. +[!code-csharp[](SuperLinq/ZipShortest/ZipShortest4.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.ZipShortest``5(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2},System.Collections.Generic.IEnumerable{``3},System.Func{``0,``1,``2,``3,``4}) +example: [*content] +--- +The following code example demonstrates how to use the `ZipShortest` to merge four sequences. +[!code-csharp[](SuperLinq/ZipShortest/ZipShortest6.linq#L6-)] + diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest1.linq new file mode 100644 index 00000000..7255cc1e --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest1.linq @@ -0,0 +1,18 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, 4, 5 }; + +// Zip two sequences together +var result = seq1.ZipShortest(seq2); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(aaa, 1), (bb, 2), (c, 3), (ddd, 4)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest2.linq new file mode 100644 index 00000000..b2fa5afa --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest2.linq @@ -0,0 +1,21 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, 4, 5 }; + +// Zip two sequences together +var result = seq1 + .ZipShortest( + seq2, + (a, b) => new { A = a, B = b, }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ A = aaa, B = 1 }, { A = bb, B = 2 }, { A = c, B = 3 }, { A = ddd, B = 4 }] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest3.linq new file mode 100644 index 00000000..452c5535 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest3.linq @@ -0,0 +1,22 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", }; +var seq2 = new[] { 1, 2, 3, 4, }; +var seq3 = new[] { 20, 5, 7, 12, 42 }; + +// Zip three sequences together +var result = seq1 + .ZipShortest( + seq2, + seq3); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(aaa, 1, 20), (bb, 2, 5), (c, 3, 7)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest4.linq new file mode 100644 index 00000000..17829a23 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest4.linq @@ -0,0 +1,23 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", }; +var seq2 = new[] { 1, 2, 3, 4, }; +var seq3 = new[] { 20, 5, 7, 12, 42 }; + +// Zip three sequences together +var result = seq1 + .ZipShortest( + seq2, + seq3, + (a, b, c) => new { A = a, B = b, C = c, }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ A = aaa, B = 1, C = 20 }, { A = bb, B = 2, C = 5 }, { A = c, B = 3, C = 7 }] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest5.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest5.linq new file mode 100644 index 00000000..8faa6336 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest5.linq @@ -0,0 +1,24 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, }; +var seq3 = new[] { 20, 5, }; +var seq4 = new[] { "zz", }; + +// Zip four sequences together +var result = seq1 + .ZipShortest( + seq2, + seq3, + seq4); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [(aaa, 1, 20, zz)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest6.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest6.linq new file mode 100644 index 00000000..ea7c1840 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ZipShortest/ZipShortest6.linq @@ -0,0 +1,31 @@ + + SuperLinq + SuperLinq + + +var seq1 = new[] { "aaa", "bb", "c", "ddd", }; +var seq2 = new[] { 1, 2, 3, }; +var seq3 = new[] { 20, 5, }; +var seq4 = new[] { "zz", }; + +// Zip four sequences together +var result = seq1 + .ZipShortest( + seq2, + seq3, + seq4, + (a, b, c, d) => new + { + A = a, + B = b, + C = c, + D = d, + }); + +Console.WriteLine( + "[" + + string.Join(", ", result) + + "]"); + +// This code produces the following output: +// [{ A = aaa, B = 1, C = 20, D = zz }] diff --git a/Generators/SuperLinq.Generator/ZipShortest.sbntxt b/Generators/SuperLinq.Generator/ZipShortest.sbntxt index 2ce54290..48cc6925 100644 --- a/Generators/SuperLinq.Generator/ZipShortest.sbntxt +++ b/Generators/SuperLinq.Generator/ZipShortest.sbntxt @@ -12,22 +12,31 @@ public static partial class SuperEnumerable { {{~ for $i in 2..4 ~}} /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// is as short as the shortest input sequence. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence is as short as the shortest input sequence. /// - /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . + /// + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// or any of the input sequences is null. + /// + /// or any of the input sequences is . + /// {{~ for $j in 1..$i ~}} - /// The type of the elements of . - /// The {{ $ordinals[$j] }} sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The {{ $ordinals[$j] }} sequence of elements. + /// {{~ end ~}} public static global::System.Collections.Generic.IEnumerable ZipShortest<{{ for $j in 1..$i }}T{{ $cardinals[$j] }}, {{ end }}TResult>(this {{~ for $j in 1..$i ~}} @@ -86,22 +95,27 @@ public static partial class SuperEnumerable } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. - /// - /// This method uses deferred execution and streams its results. + /// + /// A sequence of containing corresponding elements from each + /// of the sequences. + /// + /// + /// This method uses deferred execution and streams its results. /// - /// Any of the input sequences is null. + /// + /// Any of the input sequences is . + /// {{~ for $j in 1..$i ~}} - /// The type of the elements of . - /// The {{ $ordinals[$j] }} sequence of elements. + /// + /// The type of the elements of . + /// + /// + /// The {{ $ordinals[$j] }} sequence of elements. + /// {{~ end ~}} public static global::System.Collections.Generic.IEnumerable<({{~ for $j in 1..$i ~}}T{{ $cardinals[$j] }}{{ if !for.last }},{{ end }}{{ end }})> ZipShortest<{{~ for $j in 1..$i ~}}T{{ $cardinals[$j] }}{{ if !for.last }},{{ end }}{{ end }}>(this diff --git a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ZipShortest.g.cs b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ZipShortest.g.cs index 15f4bde1..fba048a6 100644 --- a/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ZipShortest.g.cs +++ b/Source/SuperLinq/Generated/SuperLinq.Generator/SuperLinq.Generator.Generator/ZipShortest.g.cs @@ -3,23 +3,36 @@ public static partial class SuperEnumerable { /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// is as short as the shortest input sequence. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence is as short as the shortest input sequence. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable ZipShortest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -43,23 +56,32 @@ public static partial class SuperEnumerable } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. + /// + /// A sequence of containing corresponding elements from each + /// of the sequences. + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(TFirst, TSecond)> ZipShortest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second) => ZipShortest(first, second, global::System.ValueTuple.Create); private sealed class ZipShortestIterator : ListIterator { @@ -92,25 +114,42 @@ protected override TResult ElementAt(int index) } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// is as short as the shortest input sequence. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence is as short as the shortest input sequence. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable ZipShortest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -136,25 +175,38 @@ protected override TResult ElementAt(int index) } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. + /// + /// A sequence of containing corresponding elements from each + /// of the sequences. + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(TFirst, TSecond, TThird)> ZipShortest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third) => ZipShortest(first, second, third, global::System.ValueTuple.Create); private sealed class ZipShortestIterator : ListIterator { @@ -189,27 +241,48 @@ protected override TResult ElementAt(int index) } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// is as short as the shortest input sequence. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence is as short as the shortest input sequence. /// /// - /// The type of the elements of the result sequence. - /// A projection function that combines - /// elements from all of the sequences. - /// A sequence of elements returned by . + /// The type of the elements of the result sequence. + /// + /// + /// A projection function that combines elements from all of the sequences. + /// + /// + /// A sequence of elements returned by . + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// or any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. + /// + /// or any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable ZipShortest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth, global::System.Func resultSelector) { global::CommunityToolkit.Diagnostics.Guard.IsNotNull(first); @@ -237,27 +310,44 @@ protected override TResult ElementAt(int index) } /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. + /// Returns a projection of tuples, where each tuple contains the N-th element from each of the argument + /// sequences. The resulting sequence will always be as long as the longest of input sequences where the default + /// value of each of the shorter sequence element types is used for padding. /// - /// A sequence of - /// - /// containing corresponding elements from each of the sequences. + /// + /// A sequence of containing corresponding elements from each + /// of the sequences. + /// /// - /// This method uses deferred execution and streams its results. + /// This method uses deferred execution and streams its results. /// - /// Any of the input sequences is null. - /// The type of the elements of . - /// The first sequence of elements. - /// The type of the elements of . - /// The second sequence of elements. - /// The type of the elements of . - /// The third sequence of elements. - /// The type of the elements of . - /// The fourth sequence of elements. + /// + /// Any of the input sequences is . + /// + /// + /// The type of the elements of . + /// + /// + /// The first sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The second sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The third sequence of elements. + /// + /// + /// The type of the elements of . + /// + /// + /// The fourth sequence of elements. + /// public static global::System.Collections.Generic.IEnumerable<(TFirst, TSecond, TThird, TFourth)> ZipShortest(this global::System.Collections.Generic.IEnumerable first, global::System.Collections.Generic.IEnumerable second, global::System.Collections.Generic.IEnumerable third, global::System.Collections.Generic.IEnumerable fourth) => ZipShortest(first, second, third, fourth, global::System.ValueTuple.Create); private sealed class ZipShortestIterator : ListIterator { From a6907be039e78568c416e98b716be97513c3ca00 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 13:39:14 -0600 Subject: [PATCH 122/124] Update documentation for `Window` --- .../SuperLinq.SuperEnumerable.Window.md | 27 ++++ .../apidoc/SuperLinq/Window/Window1.linq | 28 ++++ .../apidoc/SuperLinq/Window/Window2.linq | 31 ++++ .../apidoc/SuperLinq/Window/Window3.linq | 32 ++++ .../apidoc/SuperLinq/Window/Window4.linq | 33 ++++ Source/SuperLinq/Window.Buffered.cs | 144 +++++++++++++----- Source/SuperLinq/Window.cs | 28 +++- 7 files changed, 274 insertions(+), 49 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Window.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Window.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Window.md new file mode 100644 index 00000000..8a10659a --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.Window.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.Window``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `Window`. +[!code-csharp[](SuperLinq/Window/Window1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Window``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `Window`. +[!code-csharp[](SuperLinq/Window/Window2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Window``2(System.Collections.Generic.IEnumerable{``0},``0[],System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `Window`. +[!code-csharp[](SuperLinq/Window/Window3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.Window``2(System.Collections.Generic.IEnumerable{``0},``0[],System.Int32,System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `Window`. +[!code-csharp[](SuperLinq/Window/Window4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window1.linq new file mode 100644 index 00000000..585d06a1 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window1.linq @@ -0,0 +1,28 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Get a sliding window over the sequence +var result = sequence.Window(3); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window2.linq new file mode 100644 index 00000000..37f5d473 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window2.linq @@ -0,0 +1,31 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Break the sequence of numbers into three chunks of 3 and one chunk of 1 +var result = sequence + .Window( + 3, + c => " [" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window3.linq new file mode 100644 index 00000000..fb7a7743 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window3.linq @@ -0,0 +1,32 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Break the sequence of numbers into three chunks of 3 and one chunk of 1 +var buffer = new int[3]; +var result = sequence + .Window( + buffer, + c => " [" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window4.linq new file mode 100644 index 00000000..949fcd80 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Window/Window4.linq @@ -0,0 +1,33 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Break the sequence of numbers into three chunks of 3 and one chunk of 1 +var buffer = new int[5]; +var result = sequence + .Window( + buffer, + 3, + c => " [" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10] +// ] diff --git a/Source/SuperLinq/Window.Buffered.cs b/Source/SuperLinq/Window.Buffered.cs index 7f90b2ee..82e6e336 100644 --- a/Source/SuperLinq/Window.Buffered.cs +++ b/Source/SuperLinq/Window.Buffered.cs @@ -3,24 +3,46 @@ public static partial class SuperEnumerable { /// - /// Processes a sequence into a series of subsequences representing a windowed subset of the original, and then - /// projecting them into a new form. + /// Processes a sequence into a series of subsequences representing a windowed subset of the original, and then + /// projecting them into a new form. /// - /// The type of the elements of . - /// The type of the value return by . - /// The sequence to evaluate a sliding window over. - /// The size (number of elements) in each window. - /// A transform function to apply to each window. - /// An whose elements are the result of invoking the transform function on - /// each window of . + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// The sequence to evaluate a sliding window over. + /// + /// + /// The size (number of elements) in each window. + /// + /// + /// A transform function to apply to each window. + /// + /// + /// An whose elements are the result of invoking the transform function on each + /// window of . + /// + /// + /// is . + /// + /// + /// is below 1. + /// /// /// - /// The number of sequences returned is: Max(0, .Count() - + - /// 1)
Returned subsequences are buffered, but the overall operation is streamed.
+ /// A window can contain fewer elements than , especially as it slides over the start of + /// the sequence. ///
/// - /// In this overload of Window, a single array of length is allocated as a buffer for - /// all subsequences. + /// In this overload of Window, a single array of length is allocated as a + /// buffer for all subsequences. + ///
+ /// + /// This operator uses deferred execution and streams its results. + /// ///
public static IEnumerable Window( this IEnumerable source, @@ -35,25 +57,42 @@ public static IEnumerable Window( } /// - /// Processes a sequence into a series of subsequences representing a windowed subset of the original, and then - /// projecting them into a new form. + /// Processes a sequence into a series of subsequences representing a windowed subset of the original, and then + /// projecting them into a new form. /// - /// The type of the elements of . - /// The type of the value return by . - /// The sequence to evaluate a sliding window over. - /// An array to use as a buffer for each subsequence. - /// A transform function to apply to each window. - /// An whose elements are the result of invoking the transform function on - /// each window of . + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// The sequence to evaluate a sliding window over. + /// + /// + /// An array to use as a buffer for each subsequence. + /// + /// + /// A transform function to apply to each window. + /// + /// + /// An whose elements are the result of invoking the transform function on each + /// window of . + /// + /// + /// is . + /// /// /// - /// The number of sequences returned is: Max(0, .Count() - .Length + 1)
Returned subsequences are buffered, but the overall operation is - /// streamed.
+ /// A window can contain fewer elements than .Length, especially as it slides + /// over the start of the sequence. + ///
+ /// + /// In this overload of Window, is used as a common buffer for all + /// subsequences. /// /// - /// In this overload of Window, is used as a common buffer for all - /// subsequences. + /// This operator uses deferred execution and streams its results. /// ///
public static IEnumerable Window( @@ -69,28 +108,49 @@ public static IEnumerable Window( } /// - /// Processes a sequence into a series of subsequences representing a windowed subset of the original, and then - /// projecting them into a new form. + /// Processes a sequence into a series of subsequences representing a windowed subset of the original, and then + /// projecting them into a new form. /// - /// The type of the elements of . - /// The type of the value return by . - /// The sequence to evaluate a sliding window over. - /// An array to use as a buffer for each subsequence. - /// The size (number of elements) in each window. - /// A transform function to apply to each window. - /// An whose elements are the result of invoking the transform function on - /// each window of . + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// The sequence to evaluate a sliding window over. + /// + /// + /// An array to use as a buffer for each subsequence. + /// + /// + /// The size (number of elements) in each window. + /// + /// + /// A transform function to apply to each window. + /// + /// + /// An whose elements are the result of invoking the transform function on each + /// window of . + /// + /// + /// is . + /// + /// + /// is below 1 or above .Length. + /// /// /// - /// The number of sequences returned is: Max(0, .Count() - + - /// 1)
Returned subsequences are buffered, but the overall operation is streamed.
+ /// A window can contain fewer elements than , especially as it slides over the start of + /// the sequence. ///
/// - /// In this overload of Window, is used as a common buffer for all subsequences. + /// In this overload of Window, is used as a common buffer for all + /// subsequences.
This overload is provided to ease usage of common buffers, such as those rented from , which may return an array larger than requested. ///
/// - /// This overload is provided to ease usage of common buffers, such as those rented from , which may return an array larger than requested. + /// This operator uses deferred execution and streams its results. /// ///
public static IEnumerable Window( diff --git a/Source/SuperLinq/Window.cs b/Source/SuperLinq/Window.cs index 6618c6f9..4ae07d2c 100644 --- a/Source/SuperLinq/Window.cs +++ b/Source/SuperLinq/Window.cs @@ -3,16 +3,30 @@ public static partial class SuperEnumerable { /// - /// Processes a sequence into a series of subsequences representing a windowed subset of the original + /// Processes a sequence into a series of subsequences representing a windowed subset of the original /// + /// + /// The type of the elements of the source sequence + /// + /// + /// The sequence to evaluate a sliding window over + /// + /// + /// The size (number of elements) in each window + /// + /// + /// A series of sequences representing each sliding window subsequence + /// + /// + /// is . + /// + /// + /// is below 1. + /// /// - /// The number of sequences returned is: Max(0, .Count() - + 1)
- /// Returned subsequences are buffered, but the overall operation is streamed.
+ /// The number of sequences returned is: Max(0, .Count() - + + /// 1)
Returned subsequences are buffered, but the overall operation is streamed. ///
- /// The type of the elements of the source sequence - /// The sequence to evaluate a sliding window over - /// The size (number of elements) in each window - /// A series of sequences representing each sliding window subsequence public static IEnumerable> Window(this IEnumerable source, int size) { Guard.IsNotNull(source); From ea0e521e2c407f56923394bb666ea8ad428e5109 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 13:39:27 -0600 Subject: [PATCH 123/124] Update documentation for `WindowLeft` --- .../SuperLinq.SuperEnumerable.WindowLeft.md | 27 +++ .../SuperLinq/WindowLeft/WindowLeft1.linq | 30 +++ .../SuperLinq/WindowLeft/WindowLeft2.linq | 33 +++ .../SuperLinq/WindowLeft/WindowLeft3.linq | 34 ++++ .../SuperLinq/WindowLeft/WindowLeft4.linq | 35 ++++ Source/SuperLinq/WindowLeft.Buffered.cs | 190 +++++++++--------- Source/SuperLinq/WindowLeft.cs | 48 ++--- 7 files changed, 273 insertions(+), 124 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WindowLeft.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WindowLeft.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WindowLeft.md new file mode 100644 index 00000000..90c1f664 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WindowLeft.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.WindowLeft``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `WindowLeft`. +[!code-csharp[](SuperLinq/WindowLeft/WindowLeft1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.WindowLeft``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `WindowLeft`. +[!code-csharp[](SuperLinq/WindowLeft/WindowLeft2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.WindowLeft``2(System.Collections.Generic.IEnumerable{``0},``0[],System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `WindowLeft`. +[!code-csharp[](SuperLinq/WindowLeft/WindowLeft3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.WindowLeft``2(System.Collections.Generic.IEnumerable{``0},``0[],System.Int32,System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `WindowLeft`. +[!code-csharp[](SuperLinq/WindowLeft/WindowLeft4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft1.linq new file mode 100644 index 00000000..0f14c5c7 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft1.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Get a sliding window over the sequence +var result = sequence.WindowLeft(3); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10], +// [9, 10], +// [10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft2.linq new file mode 100644 index 00000000..c96e18ba --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft2.linq @@ -0,0 +1,33 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Get a sliding window over the sequence +var result = sequence + .WindowLeft( + 3, + c => " [" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10], +// [9, 10], +// [10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft3.linq new file mode 100644 index 00000000..a839e2c0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft3.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Get a sliding window over the sequence +var buffer = new int[3]; +var result = sequence + .WindowLeft( + buffer, + c => " [" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10], +// [9, 10], +// [10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft4.linq new file mode 100644 index 00000000..7ff8d1e4 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowLeft/WindowLeft4.linq @@ -0,0 +1,35 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Get a sliding window over the sequence +var buffer = new int[5]; +var result = sequence + .WindowLeft( + buffer, + 3, + c => " [" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10], +// [9, 10], +// [10] +// ] diff --git a/Source/SuperLinq/WindowLeft.Buffered.cs b/Source/SuperLinq/WindowLeft.Buffered.cs index 4b1c36c3..1cc4da7f 100644 --- a/Source/SuperLinq/WindowLeft.Buffered.cs +++ b/Source/SuperLinq/WindowLeft.Buffered.cs @@ -3,47 +3,45 @@ public static partial class SuperEnumerable { /// - /// Creates a left-aligned sliding window over the source sequence of a given size. + /// Creates a right-aligned sliding window over the source sequence of a given size. /// - /// The type of the elements of . - /// The type of the value return by . - /// The sequence over which to create the sliding window. - /// Size of the sliding window. - /// A transform function to apply to each window. - /// A sequence representing each sliding window. - /// or is - /// null. - /// is below 1. + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// The sequence over which to create the sliding window. + /// + /// + /// Size of the sliding window. + /// + /// + /// A transform function to apply to each window. + /// + /// + /// A sequence representing each sliding window. + /// + /// + /// or is . + /// + /// + /// is below 1. + /// /// /// - /// A window can contain fewer elements than , especially as it slides over the start of the - /// sequence. + /// A window can contain fewer elements than , especially as it slides over the start of + /// the sequence. /// /// - /// In this overload of WindowLeft, a single array of length is allocated as a buffer for - /// all subsequences. + /// In this overload of WindowLeft, a single array of length is allocated as a + /// buffer for all subsequences. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// /// - /// - /// "AVG(" + w.ToDelimitedString(",") + ") = " + w.Average()) - /// .ToDelimitedString(Environment.NewLine)); - /// - /// // Output: - /// // AVG(1,2,3) = 2 - /// // AVG(2,3,4) = 3 - /// // AVG(3,4,5) = 4 - /// // AVG(4,5) = 4.5 - /// // AVG(5) = 5 - /// ]]> - /// public static IEnumerable WindowLeft( this IEnumerable source, int size, @@ -57,46 +55,42 @@ public static IEnumerable WindowLeft( } /// - /// Creates a right-aligned sliding window over the source sequence of a given size. + /// Creates a right-aligned sliding window over the source sequence of a given size. /// - /// The type of the elements of . - /// The type of the value return by . - /// The sequence over which to create the sliding window. - /// An array to use as a buffer for each subsequence. - /// A transform function to apply to each window. - /// A sequence representing each sliding window. - /// , , or is null. + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// The sequence over which to create the sliding window. + /// + /// + /// An array to use as a buffer for each subsequence. + /// + /// + /// A transform function to apply to each window. + /// + /// + /// A sequence representing each sliding window. + /// + /// + /// , , or is null. + /// /// /// - /// A window can contain fewer elements than .Length, especially as it slides over - /// the start of the sequence. + /// A window can contain fewer elements than .Length, especially as it slides + /// over the start of the sequence. /// /// - /// In this overload of WindowLeft, is used as a common buffer for all - /// subsequences. + /// In this overload of WindowLeft, is used as a common buffer for all + /// subsequences. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// /// - /// - /// "AVG(" + w.ToDelimitedString(",") + ") = " + w.Average()) - /// .ToDelimitedString(Environment.NewLine)); - /// - /// // Output: - /// // AVG(1,2,3) = 2 - /// // AVG(2,3,4) = 3 - /// // AVG(3,4,5) = 4 - /// // AVG(4,5) = 4.5 - /// // AVG(5) = 5 - /// ]]> - /// public static IEnumerable WindowLeft( this IEnumerable source, TSource[] array, @@ -110,50 +104,50 @@ public static IEnumerable WindowLeft( } /// - /// Creates a right-aligned sliding window over the source sequence of a given size. + /// Creates a right-aligned sliding window over the source sequence of a given size. /// - /// The type of the elements of . - /// The type of the value return by . - /// The sequence over which to create the sliding window. - /// Size of the sliding window. - /// An array to use as a buffer for each subsequence. - /// A transform function to apply to each window. - /// A sequence representing each sliding window. - /// , , or is null. - /// is below 1 or above .Length. + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// The sequence over which to create the sliding window. + /// + /// + /// Size of the sliding window. + /// + /// + /// An array to use as a buffer for each subsequence. + /// + /// + /// A transform function to apply to each window. + /// + /// + /// A sequence representing each sliding window. + /// + /// + /// , , or is . + /// + /// + /// is below 1 or above .Length. + /// /// /// - /// A window can contain fewer elements than , especially as it slides over the start of the - /// sequence. + /// A window can contain fewer elements than , especially as it slides over the start of + /// the sequence. /// /// - /// In this overload of WindowLeft, is used as a common buffer for all - /// subsequences.
This overload is provided to ease usage of common buffers, such as those rented from , which may return an array larger than requested. + /// In this overload of WindowLeft, is used as a common buffer for all + /// subsequences.
This overload is provided to ease usage of common buffers, such as those rented from , which may return an array larger than requested. ///
/// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// ///
- /// - /// "AVG(" + w.ToDelimitedString(",") + ") = " + w.Average()) - /// .ToDelimitedString(Environment.NewLine)); - /// - /// // Output: - /// // AVG(1,2,3) = 2 - /// // AVG(2,3,4) = 3 - /// // AVG(3,4,5) = 4 - /// // AVG(4,5) = 4.5 - /// // AVG(5) = 5 - /// ]]> - /// public static IEnumerable WindowLeft( this IEnumerable source, TSource[] array, diff --git a/Source/SuperLinq/WindowLeft.cs b/Source/SuperLinq/WindowLeft.cs index b8500bb2..5ffd5c17 100644 --- a/Source/SuperLinq/WindowLeft.cs +++ b/Source/SuperLinq/WindowLeft.cs @@ -3,39 +3,35 @@ public static partial class SuperEnumerable { /// - /// Creates a left-aligned sliding window of a given size over the - /// source sequence. + /// Creates a left-aligned sliding window of a given size over the source sequence. /// /// - /// The type of the elements of . + /// The type of the elements of . + /// /// - /// The sequence over which to create the sliding window. - /// Size of the sliding window. - /// A sequence representing each sliding window. + /// The sequence over which to create the sliding window. + /// + /// + /// Size of the sliding window. + /// + /// + /// A sequence representing each sliding window. + /// + /// + /// is . + /// + /// + /// is below 1. + /// /// /// - /// A window can contain fewer elements than , - /// especially as it slides over the end of the sequence. + /// A window can contain fewer elements than , especially as it slides over the end of + /// the sequence. + ///
/// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. + ///
///
- /// - /// "AVG(" + w.ToDelimitedString(",") + ") = " + w.Average()) - /// .ToDelimitedString(Environment.NewLine)); - /// - /// // Output: - /// // AVG(1,2,3) = 2 - /// // AVG(2,3,4) = 3 - /// // AVG(3,4,5) = 4 - /// // AVG(4,5) = 4.5 - /// // AVG(5) = 5 - /// ]]> - /// public static IEnumerable> WindowLeft(this IEnumerable source, int size) { Guard.IsNotNull(source); From 411150b4ad16df962fcd4ef4549a23cd3292b281 Mon Sep 17 00:00:00 2001 From: Stuart Turner Date: Wed, 22 Nov 2023 13:39:37 -0600 Subject: [PATCH 124/124] Update documentation for `WindowRight` --- .../SuperLinq.SuperEnumerable.WindowRight.md | 27 +++ .../SuperLinq/WindowRight/WindowRight1.linq | 30 +++ .../SuperLinq/WindowRight/WindowRight2.linq | 33 +++ .../SuperLinq/WindowRight/WindowRight3.linq | 34 ++++ .../SuperLinq/WindowRight/WindowRight4.linq | 35 ++++ Source/SuperLinq/WindowRight.Buffered.cs | 189 +++++++++--------- Source/SuperLinq/WindowRight.cs | 50 +++-- 7 files changed, 273 insertions(+), 125 deletions(-) create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WindowRight.md create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight1.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight2.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight3.linq create mode 100644 Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight4.linq diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WindowRight.md b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WindowRight.md new file mode 100644 index 00000000..87830c63 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq.SuperEnumerable.WindowRight.md @@ -0,0 +1,27 @@ +--- +uid: SuperLinq.SuperEnumerable.WindowRight``1(System.Collections.Generic.IEnumerable{``0},System.Int32) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `WindowRight`. +[!code-csharp[](SuperLinq/WindowRight/WindowRight1.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.WindowRight``2(System.Collections.Generic.IEnumerable{``0},System.Int32,System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `WindowRight`. +[!code-csharp[](SuperLinq/WindowRight/WindowRight2.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.WindowRight``2(System.Collections.Generic.IEnumerable{``0},``0[],System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `WindowRight`. +[!code-csharp[](SuperLinq/WindowRight/WindowRight3.linq#L6-)] + +--- +uid: SuperLinq.SuperEnumerable.WindowRight``2(System.Collections.Generic.IEnumerable{``0},``0[],System.Int32,System.Func{System.Collections.Generic.IReadOnlyList{``0},``1}) +example: [*content] +--- +The following code example demonstrates how to generate a sliding window over a sequence using `WindowRight`. +[!code-csharp[](SuperLinq/WindowRight/WindowRight4.linq#L6-)] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight1.linq new file mode 100644 index 00000000..4aeb3561 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight1.linq @@ -0,0 +1,30 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Get a sliding window over the sequence +var result = sequence.WindowRight(3); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result.Select(c => " [" + string.Join(", ", c) + "]")) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1], +// [1, 2], +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight2.linq new file mode 100644 index 00000000..e5349452 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight2.linq @@ -0,0 +1,33 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Get a sliding window over the sequence +var result = sequence + .WindowRight( + 3, + c => " [" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1], +// [1, 2], +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight3.linq new file mode 100644 index 00000000..b5638ca6 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight3.linq @@ -0,0 +1,34 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Get a sliding window over the sequence +var buffer = new int[3]; +var result = sequence + .WindowRight( + buffer, + c => " [" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1], +// [1, 2], +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10] +// ] diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight4.linq new file mode 100644 index 00000000..a5ac01f0 --- /dev/null +++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/WindowRight/WindowRight4.linq @@ -0,0 +1,35 @@ + + SuperLinq + SuperLinq + + +var sequence = Enumerable.Range(1, 10); + +// Get a sliding window over the sequence +var buffer = new int[5]; +var result = sequence + .WindowRight( + buffer, + 3, + c => " [" + string.Join(", ", c) + "]"); + +Console.WriteLine( + "[" + Environment.NewLine + + string.Join( + ", " + Environment.NewLine, + result) + + Environment.NewLine + "]"); + +// This code produces the following output: +// [ +// [1], +// [1, 2], +// [1, 2, 3], +// [2, 3, 4], +// [3, 4, 5], +// [4, 5, 6], +// [5, 6, 7], +// [6, 7, 8], +// [7, 8, 9], +// [8, 9, 10] +// ] diff --git a/Source/SuperLinq/WindowRight.Buffered.cs b/Source/SuperLinq/WindowRight.Buffered.cs index 1b7a3519..a3749295 100644 --- a/Source/SuperLinq/WindowRight.Buffered.cs +++ b/Source/SuperLinq/WindowRight.Buffered.cs @@ -3,47 +3,45 @@ public static partial class SuperEnumerable { /// - /// Creates a right-aligned sliding window over the source sequence of a given size. + /// Creates a right-aligned sliding window over the source sequence of a given size. /// - /// The type of the elements of . - /// The type of the value return by . - /// The sequence over which to create the sliding window. - /// Size of the sliding window. - /// A transform function to apply to each window. - /// A sequence representing each sliding window. - /// or is - /// null. - /// is below 1. + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// The sequence over which to create the sliding window. + /// + /// + /// Size of the sliding window. + /// + /// + /// A transform function to apply to each window. + /// + /// + /// A sequence representing each sliding window. + /// + /// + /// or is . + /// + /// + /// is below 1. + /// /// /// - /// A window can contain fewer elements than , especially as it slides over the start of the - /// sequence. + /// A window can contain fewer elements than , especially as it slides over the start of + /// the sequence. /// /// - /// In this overload of WindowRight, a single array of length is allocated as a buffer for - /// all subsequences. + /// In this overload of WindowRight, a single array of length is allocated as a + /// buffer for all subsequences. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// /// - /// - /// "AVG(" + w.ToDelimitedString(",") + ") = " + w.Average()) - /// .ToDelimitedString(Environment.NewLine)); - /// - /// // Output: - /// // AVG(1) = 1 - /// // AVG(1,2) = 1.5 - /// // AVG(1,2,3) = 2 - /// // AVG(2,3,4) = 3 - /// // AVG(3,4,5) = 4 - /// ]]> - /// public static IEnumerable WindowRight( this IEnumerable source, int size, @@ -57,46 +55,42 @@ public static IEnumerable WindowRight( } /// - /// Creates a right-aligned sliding window over the source sequence of a given size. + /// Creates a right-aligned sliding window over the source sequence of a given size. /// - /// The type of the elements of . - /// The type of the value return by . - /// The sequence over which to create the sliding window. - /// An array to use as a buffer for each subsequence. - /// A transform function to apply to each window. - /// A sequence representing each sliding window. - /// , , or is null. + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// The sequence over which to create the sliding window. + /// + /// + /// An array to use as a buffer for each subsequence. + /// + /// + /// A transform function to apply to each window. + /// + /// + /// A sequence representing each sliding window. + /// + /// + /// or is . + /// /// /// - /// A window can contain fewer elements than .Length, especially as it slides over - /// the start of the sequence. + /// A window can contain fewer elements than .Length, especially as it slides + /// over the start of the sequence. /// /// - /// In this overload of WindowRight, is used as a common buffer for all - /// subsequences. + /// In this overload of WindowRight, is used as a common buffer for all + /// subsequences. /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// /// - /// - /// "AVG(" + w.ToDelimitedString(",") + ") = " + w.Average()) - /// .ToDelimitedString(Environment.NewLine)); - /// - /// // Output: - /// // AVG(1) = 1 - /// // AVG(1,2) = 1.5 - /// // AVG(1,2,3) = 2 - /// // AVG(2,3,4) = 3 - /// // AVG(3,4,5) = 4 - /// ]]> - /// public static IEnumerable WindowRight( this IEnumerable source, TSource[] array, @@ -110,50 +104,49 @@ public static IEnumerable WindowRight( } /// - /// Creates a right-aligned sliding window over the source sequence of a given size. + /// Creates a right-aligned sliding window over the source sequence of a given size. /// - /// The type of the elements of . - /// The type of the value return by . - /// The sequence over which to create the sliding window. - /// Size of the sliding window. - /// An array to use as a buffer for each subsequence. - /// A transform function to apply to each window. - /// A sequence representing each sliding window. - /// , , or is null. - /// is below 1 or above .Length. + /// + /// The type of the elements of . + /// + /// + /// The type of the value return by . + /// + /// + /// The sequence over which to create the sliding window. + /// + /// + /// An array to use as a buffer for each subsequence. + /// + /// + /// Size of the sliding window. + /// + /// + /// A transform function to apply to each window. + /// + /// + /// A sequence representing each sliding window. + /// + /// + /// or is . + /// + /// + /// is below 1 or above .Length. + /// /// /// - /// A window can contain fewer elements than , especially as it slides over the start of the - /// sequence. + /// A window can contain fewer elements than , especially as it slides over the start of + /// the sequence. /// /// - /// In this overload of WindowRight, is used as a common buffer for all - /// subsequences.
This overload is provided to ease usage of common buffers, such as those rented from , which may return an array larger than requested. + /// In this overload of WindowRight, is used as a common buffer for all + /// subsequences.
This overload is provided to ease usage of common buffers, such as those rented from , which may return an array larger than requested. ///
/// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. /// ///
- /// - /// "AVG(" + w.ToDelimitedString(",") + ") = " + w.Average()) - /// .ToDelimitedString(Environment.NewLine)); - /// - /// // Output: - /// // AVG(1) = 1 - /// // AVG(1,2) = 1.5 - /// // AVG(1,2,3) = 2 - /// // AVG(2,3,4) = 3 - /// // AVG(3,4,5) = 4 - /// ]]> - /// public static IEnumerable WindowRight( this IEnumerable source, TSource[] array, diff --git a/Source/SuperLinq/WindowRight.cs b/Source/SuperLinq/WindowRight.cs index ec1c032f..e28e46ad 100644 --- a/Source/SuperLinq/WindowRight.cs +++ b/Source/SuperLinq/WindowRight.cs @@ -3,39 +3,35 @@ public static partial class SuperEnumerable { /// - /// Creates a right-aligned sliding window over the source sequence of a given size. + /// Creates a right-aligned sliding window over the source sequence of a given size. /// /// - /// The type of the elements of . - /// The sequence over which to create the sliding window. - /// Size of the sliding window. - /// A sequence representing each sliding window. - /// is null. - /// is below 1. + /// The type of the elements of . + /// + /// + /// The sequence over which to create the sliding window. + /// + /// + /// Size of the sliding window. + /// + /// + /// A sequence representing each sliding window. + /// + /// + /// is . + /// + /// + /// is below 1. + /// /// /// - /// A window can contain fewer elements than , especially as it slides over the start of the - /// sequence. + /// A window can contain fewer elements than , especially as it slides over the start of + /// the sequence. + ///
/// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred execution and streams its results. + ///
///
- /// - /// "AVG(" + w.ToDelimitedString(",") + ") = " + w.Average()) - /// .ToDelimitedString(Environment.NewLine)); - /// - /// // Output: - /// // AVG(1) = 1 - /// // AVG(1,2) = 1.5 - /// // AVG(1,2,3) = 2 - /// // AVG(2,3,4) = 3 - /// // AVG(3,4,5) = 4 - /// ]]> - /// public static IEnumerable> WindowRight(this IEnumerable source, int size) { Guard.IsNotNull(source);