From 4b510f64484449e58f11c775c2b8790ce0440ae8 Mon Sep 17 00:00:00 2001 From: ig Date: Thu, 4 May 2023 09:42:57 +0200 Subject: [PATCH] add GroupUntil extension --- csharp/Lib/Utils/EnumerableUtils.cs | 43 +++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/csharp/Lib/Utils/EnumerableUtils.cs b/csharp/Lib/Utils/EnumerableUtils.cs index 609258c37..6811c7e30 100644 --- a/csharp/Lib/Utils/EnumerableUtils.cs +++ b/csharp/Lib/Utils/EnumerableUtils.cs @@ -68,6 +68,8 @@ public static class EnumerableUtils // } + + public static Queue ToQueue(this IEnumerable ts) { var q = new Queue(); @@ -141,6 +143,7 @@ public static class EnumerableUtils } } + public static IEnumerable<(T left, T right)> Pairwise(this IEnumerable ts, T seed) { using var e = ts.GetEnumerator(); @@ -363,6 +366,46 @@ public static class EnumerableUtils } + + + + [SuppressMessage("ReSharper", "AccessToDisposedClosure")] + public static IEnumerable> GroupUntil(this IEnumerable sequence, Func splitBetween) + { + using var e = sequence.GetEnumerator(); + + if(!e.MoveNext()) + yield break; // empty sequence + + var moreInSeq = false; + var moreInGroup = false; + + do + { + yield return GetGroup(); + while (moreInGroup) + MoveNext(); + } + while (moreInSeq); + + void MoveNext() + { + var prev = e.Current; + moreInSeq = e.MoveNext(); + moreInGroup = moreInSeq && !splitBetween(prev, e.Current); + } + + IEnumerable GetGroup() + { + do + { + yield return e.Current; + MoveNext(); + } + while (moreInGroup); + } + } + public static IEnumerable NotNull(this IEnumerable ts) { return ts.Where(t => t != null)!;