From 66bf7f33175cddbfb3407f61f1cdb2b7a25659b8 Mon Sep 17 00:00:00 2001 From: pepelev Date: Wed, 1 Oct 2025 19:35:21 +0500 Subject: [PATCH] Add Max and Min for spans --- src/Comparation/Comparation.csproj | 2 +- src/Comparation/OrderExtensions.cs | 104 +++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/src/Comparation/Comparation.csproj b/src/Comparation/Comparation.csproj index 6047cfb..ae0b150 100644 --- a/src/Comparation/Comparation.csproj +++ b/src/Comparation/Comparation.csproj @@ -4,7 +4,7 @@ ..\..\bin\Comparation true netstandard2.0;netstandard2.1;net6 - 9 + 13 enable diff --git a/src/Comparation/OrderExtensions.cs b/src/Comparation/OrderExtensions.cs index 5d8ea5e..e863d66 100644 --- a/src/Comparation/OrderExtensions.cs +++ b/src/Comparation/OrderExtensions.cs @@ -20,10 +20,114 @@ public static T Max(this IComparer order, T a, T b) => order.Sign(a, b) == ? a : b; +#if NET6_0_OR_GREATER + public static T Max(this IComparer order, T first, params ReadOnlySpan others) + { + var max = first; + foreach (var another in others) + { + max = order.Max(another, max); + } + + return max; + } + + public static T MaxOrThrow(this IComparer order, params ReadOnlySpan items) + { + if (items.Length == 0) + { + throw new ArgumentException("is empty", paramName: nameof(items)); + } + + var max = items[0]; + for (var i = 1; i < items.Length; i++) + { + var item = items[i]; + max = order.Max(max, item); + } + + return max; + } + + public static int MaxIndexOrThrow(this IComparer order, params ReadOnlySpan items) + { + if (items.Length == 0) + { + throw new ArgumentException("is empty", paramName: nameof(items)); + } + + var max = items[0]; + var maxIndex = 0; + for (var i = 1; i < items.Length; i++) + { + var item = items[i]; + if (order.Sign(item, max) == Order.Sign.Greater) + { + max = item; + maxIndex = i; + } + } + + return maxIndex; + } +#endif + public static T Min(this IComparer order, T a, T b) => order.Sign(a, b) != Order.Sign.Greater ? a : b; +#if NET6_0_OR_GREATER + public static T Min(this IComparer order, T first, params ReadOnlySpan others) + { + var min = first; + foreach (var another in others) + { + min = order.Min(min, another); + } + + return min; + } + + public static T MinOrThrow(this IComparer order, params ReadOnlySpan items) + { + if (items.Length == 0) + { + throw new ArgumentException("is empty", paramName: nameof(items)); + } + + var min = items[0]; + for (var i = 1; i < items.Length; i++) + { + var item = items[i]; + min = order.Min(min, item); + } + + return min; + } + + public static int MinIndexOrThrow(this IComparer order, params ReadOnlySpan items) + { + if (items.Length == 0) + { + throw new ArgumentException("is empty", paramName: nameof(items)); + } + + var min = items[0]; + var minIndex = 0; + for (var i = 1; i < items.Length; i++) + { + var item = items[i]; + if (order.Sign(item, min) == Order.Sign.Less) + { + min = item; + minIndex = i; + } + } + + return minIndex; + } +#endif + public static IComparer Invert(this IComparer order) => Comparer.Create( (a, b) => order.Compare(b, a) );