Skip to content

Commit e69b745

Browse files
committed
Change: Refactor Span LINQ methods to reuse ReadOnlySpan versions
1 parent 30f317f commit e69b745

11 files changed

+56
-115
lines changed

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqAllExtensions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ namespace CodeOfChaos.SpanLINQ;
77
// Code
88
// ---------------------------------------------------------------------------------------------------------------------
99
public static class SpanLinqAllExtensions {
10+
11+
public static bool All<T>(this in Span<T> span, Func<T, bool> predicate)
12+
=> All((ReadOnlySpan<T>)span, predicate);
13+
1014
public static bool All<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
1115
for (int i = span.Length - 1; i >= 0; i--)
1216
if (!predicate(span[i])) return false;

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqAnyExtensions.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ namespace CodeOfChaos.SpanLINQ;
77
// Code
88
// ---------------------------------------------------------------------------------------------------------------------
99
public static class SpanLinqAnyExtensions {
10+
public static bool Any<T>(this in Span<T> span)
11+
=> Any((ReadOnlySpan<T>)span);
12+
13+
public static bool Any<T>(this in ReadOnlySpan<T> span) {
14+
for (int i = span.Length - 1; i >= 0; i--)
15+
if (span[i] != null) return true;
16+
return false;
17+
}
18+
19+
public static bool Any<T>(this in Span<T> span, Func<T, bool> predicate)
20+
=> Any((ReadOnlySpan<T>)span, predicate);
21+
1022
public static bool Any<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
1123
for (int i = span.Length - 1; i >= 0; i--)
1224
if (predicate(span[i])) return true;

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqAverageExtensions.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,23 @@
33
// ---------------------------------------------------------------------------------------------------------------------
44
// ReSharper disable once CheckNamespace
55
namespace System;
6-
76
// ---------------------------------------------------------------------------------------------------------------------
87
// Code
98
// ---------------------------------------------------------------------------------------------------------------------
109
public static class SpanLinqAverageExtensions {
11-
public static double Average<T>(this in Span<T> span, Func<T, double> selector) {
12-
int length = span.Length;
13-
if (length == 0) throw new InvalidOperationException("Sequence contains no elements");
14-
double sum = 0;
15-
for (int i = span.Length - 1; i >= 0; i--) {
16-
sum += selector(span[i]);
17-
}
18-
return sum / length;
19-
}
2010

11+
public static double Average<T>(this in Span<T> span, Func<T, double> selector)
12+
=> Average((ReadOnlySpan<T>)span, selector);
13+
2114
public static double Average<T>(this in ReadOnlySpan<T> span, Func<T, double> selector) {
2215
int length = span.Length;
2316
if (length == 0) throw new InvalidOperationException("Sequence contains no elements");
17+
2418
double sum = 0;
2519
for (int i = span.Length - 1; i >= 0; i--) {
2620
sum += selector(span[i]);
2721
}
22+
2823
return sum / length;
2924
}
3025
}

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqCountExtensions.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,9 @@ namespace CodeOfChaos.SpanLINQ;
88
// Code
99
// ---------------------------------------------------------------------------------------------------------------------
1010
public static class SpanLinqCountExtensions {
11-
public static int Count<T>(this in Span<T> span, Func<T, bool> predicate) {
12-
int count = 0;
13-
for (int index = span.Length - 1; index >= 0; index--) {
14-
if (predicate(span[index])) count++;
15-
}
16-
return count;
17-
}
11+
12+
public static int Count<T>(this in Span<T> span, Func<T, bool> predicate)
13+
=> Count((ReadOnlySpan<T>)span, predicate);
1814

1915
public static int Count<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
2016
int count = 0;

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqFirstExtensions.cs

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,10 @@ namespace CodeOfChaos.SpanLINQ;
77
// Code
88
// ---------------------------------------------------------------------------------------------------------------------
99
public static class SpanLinqFirstExtensions {
10-
public static T First<T>(this in Span<T> span, Func<T, bool> predicate) {
11-
// ReSharper disable once ForCanBeConvertedToForeach
12-
for (int i = 0; i < span.Length; i++) {
13-
T element = span[i];
14-
if (predicate(element)) return element;
15-
}
16-
17-
throw new InvalidOperationException("Sequence contains no elements");
18-
}
1910

11+
public static T First<T>(this in Span<T> span, Func<T, bool> predicate)
12+
=> First((ReadOnlySpan<T>)span, predicate);
13+
2014
public static T First<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
2115
// ReSharper disable once ForCanBeConvertedToForeach
2216
for (int i = 0; i < span.Length; i++) {
@@ -27,15 +21,8 @@ public static T First<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate)
2721
throw new InvalidOperationException("Sequence contains no elements");
2822
}
2923

30-
public static T? FirstOrDefault<T>(this in Span<T> span, Func<T, bool> predicate) {
31-
// ReSharper disable once ForCanBeConvertedToForeach
32-
for (int i = 0; i < span.Length; i++) {
33-
T element = span[i];
34-
if (predicate(element)) return element;
35-
}
36-
37-
return default;
38-
}
24+
public static T? FirstOrDefault<T>(this in Span<T> span, Func<T, bool> predicate)
25+
=> FirstOrDefault((ReadOnlySpan<T>)span, predicate);
3926

4027
public static T? FirstOrDefault<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
4128
// ReSharper disable once ForCanBeConvertedToForeach

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqLastExtensions.cs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,11 @@ namespace CodeOfChaos.SpanLINQ;
77
// Code
88
// ---------------------------------------------------------------------------------------------------------------------
99
public static class SpanLinqLastExtensions {
10-
public static T Last<T>(this in Span<T> span, Func<T, bool> predicate) {
11-
// ReSharper disable once ForCanBeConvertedToForeach
12-
for (int i = span.Length - 1; i >= 0; i--) {
13-
T element = span[i];
14-
if (predicate(element)) return element;
15-
}
16-
17-
throw new InvalidOperationException("Sequence contains no elements");
18-
}
10+
11+
public static T Last<T>(this in Span<T> span, Func<T, bool> predicate)
12+
=> Last((ReadOnlySpan<T>)span, predicate);
1913

2014
public static T Last<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
21-
// ReSharper disable once ForCanBeConvertedToForeach
2215
for (int i = span.Length - 1; i >= 0; i--) {
2316
T element = span[i];
2417
if (predicate(element)) return element;
@@ -27,18 +20,10 @@ public static T Last<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
2720
throw new InvalidOperationException("Sequence contains no elements");
2821
}
2922

30-
public static T? LastOrDefault<T>(this in Span<T> span, Func<T, bool> predicate) {
31-
// ReSharper disable once ForCanBeConvertedToForeach
32-
for (int i = span.Length - 1; i >= 0; i--) {
33-
T element = span[i];
34-
if (predicate(element)) return element;
35-
}
36-
37-
return default;
38-
}
23+
public static T? LastOrDefault<T>(this in Span<T> span, Func<T, bool> predicate)
24+
=> LastOrDefault((ReadOnlySpan<T>)span, predicate);
3925

4026
public static T? LastOrDefault<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
41-
// ReSharper disable once ForCanBeConvertedToForeach
4227
for (int i = span.Length - 1; i >= 0; i--) {
4328
T element = span[i];
4429
if (predicate(element)) return element;

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqMaxExtensions.cs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,21 @@ namespace CodeOfChaos.SpanLINQ;
77
// Code
88
// ---------------------------------------------------------------------------------------------------------------------
99
public static class SpanLinqMaxExtensions {
10-
public static TResult Max<T, TResult>(this in Span<T> span, Func<T, TResult> selector)
11-
where TResult : IComparable<TResult> {
12-
if (span.Length == 0) throw new InvalidOperationException("Sequence contains no elements");
13-
14-
TResult min = selector(span[0]);
15-
for (int i = span.Length - 1; i >= 1; i--) {
16-
TResult current = selector(span[i]);
17-
if (current.CompareTo(min) > 0) min = current;
18-
}
19-
20-
return min;
21-
}
10+
11+
public static TResult Max<T, TResult>(this in Span<T> span, Func<T, TResult> selector) where TResult : IComparable<TResult>
12+
=> Max((ReadOnlySpan<T>)span, selector);
2213

2314
public static TResult Max<T, TResult>(this in ReadOnlySpan<T> span, Func<T, TResult> selector)
2415
where TResult : IComparable<TResult> {
2516
if (span.Length == 0) throw new InvalidOperationException("Sequence contains no elements");
2617

27-
TResult min = selector(span[0]);
18+
TResult max = selector(span[0]);
2819
for (int i = span.Length - 1; i >= 1; i--) {
2920
TResult current = selector(span[i]);
30-
if (current.CompareTo(min) > 0) min = current;
21+
if (current.CompareTo(max) > 0) max = current;
3122
}
3223

33-
return min;
24+
return max;
3425
}
3526

3627
}

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqMinExtensions.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,10 @@ namespace CodeOfChaos.SpanLINQ;
77
// Code
88
// ---------------------------------------------------------------------------------------------------------------------
99
public static class SpanLinqMinExtensions {
10-
public static TResult Min<T, TResult>(this in Span<T> span, Func<T, TResult> selector)
11-
where TResult : IComparable<TResult> {
12-
if (span.Length == 0) throw new InvalidOperationException("Sequence contains no elements");
13-
14-
TResult min = selector(span[0]);
15-
for (int i = span.Length - 1; i >= 1; i--) {
16-
TResult current = selector(span[i]);
17-
if (current.CompareTo(min) < 0) min = current;
18-
}
19-
20-
return min;
21-
}
22-
10+
11+
public static TResult Min<T, TResult>(this in Span<T> span, Func<T, TResult> selector) where TResult : IComparable<TResult>
12+
=> Min((ReadOnlySpan<T>)span, selector);
13+
2314
public static TResult Min<T, TResult>(this in ReadOnlySpan<T> span, Func<T, TResult> selector)
2415
where TResult : IComparable<TResult> {
2516
if (span.Length == 0) throw new InvalidOperationException("Sequence contains no elements");

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqSelectExtensions.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ namespace CodeOfChaos.SpanLINQ;
77
// Code
88
// ---------------------------------------------------------------------------------------------------------------------
99
public static class SpanLinqSelectExtensions {
10-
10+
public static void Select<TSource, TResult>(this in Span<TSource> source, Func<TSource, TResult> selector, Span<TResult> destination)
11+
=> Select((ReadOnlySpan<TSource>)source, selector, destination);
12+
1113
public static void Select<TSource, TResult>(
1214
this in ReadOnlySpan<TSource> source,
1315
Func<TSource, TResult> selector,
@@ -19,6 +21,9 @@ Span<TResult> destination
1921
destination[i] = selector(source[i]);
2022
}
2123
}
24+
25+
public static void SelectMany<TSource, TResult>(this in Span<TSource> source, Func<TSource, ReadOnlySpan<TResult>> selector, Span<TResult> destination, out int totalCount)
26+
=> SelectMany((ReadOnlySpan<TSource>)source, selector, destination, out totalCount);
2227

2328
public static void SelectMany<TSource, TResult>(
2429
this in ReadOnlySpan<TSource> source,

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqSumExtensions.cs

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,11 @@ namespace CodeOfChaos.SpanLINQ;
88
// Code
99
// ---------------------------------------------------------------------------------------------------------------------
1010
public static class SpanLinqSumExtensions {
11-
public static int Sum<T>(this in Span<T> span, Func<T, int> selector, int length = -1) {
12-
int totalGroups = 0;
13-
length = length switch {
14-
< -1 => throw new ArgumentOutOfRangeException(nameof(length)),
15-
-1 => span.Length,
16-
_ => length
17-
};
18-
19-
for (int index = 0; index < length; index++) {
20-
totalGroups += selector(span[index]);
21-
}
22-
return totalGroups;
23-
}
11+
public static int Sum<T>(this in Span<T> span, Func<T, int> selector, int length = -1)
12+
=> Sum((ReadOnlySpan<T>)span, selector, length);
2413

25-
public static int Sum<T>(this in Span<T> span, Func<T, int> selector, Range range) {
26-
int totalGroups = 0;
27-
ReadOnlySpan<T> slice = span[range];
28-
int length = slice.Length;
29-
30-
for (int index = 0; index < length; index++) {
31-
totalGroups += selector(slice[index]);
32-
}
33-
return totalGroups;
34-
}
14+
public static int Sum<T>(this in Span<T> span, Func<T, int> selector, Range range)
15+
=> Sum((ReadOnlySpan<T>)span, selector, range);
3516

3617
public static int Sum<T>(this in ReadOnlySpan<T> span, Func<T, int> selector, int length = -1) {
3718
int totalGroups = 0;

0 commit comments

Comments
 (0)