feat: add Span<T>.Replace

This commit is contained in:
Oliver Booth 2023-04-06 02:31:22 +01:00
parent bafc327ee6
commit 0621c246a0
No known key found for this signature in database
GPG Key ID: 20BEB9DC87961025
3 changed files with 51 additions and 1 deletions

View File

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- X10D: Added extension methods for `DateOnly`, for parity with `DateTime` and `DateTimeOffset`. - X10D: Added extension methods for `DateOnly`, for parity with `DateTime` and `DateTimeOffset`.
- X10D: Added math-related extension methods for `BigInteger`. - X10D: Added math-related extension methods for `BigInteger`.
- X10D: Added `Span<T>.Replace(T, T)`.
### Changed ### Changed
- X10D: `DateTime.Age(DateTime)` and `DateTimeOffset.Age(DateTimeOffset)` parameter renamed from `asOf` to `referenceDate`. - X10D: `DateTime.Age(DateTime)` and `DateTimeOffset.Age(DateTimeOffset)` parameter renamed from `asOf` to `referenceDate`.

View File

@ -46,6 +46,30 @@ public class SpanTest
Assert.That(count, Is.EqualTo(8)); Assert.That(count, Is.EqualTo(8));
} }
[Test]
public void Replace_ShouldReplaceAllElements_GivenSpanOfInt32()
{
Span<int> span = stackalloc int[16] {1, 2, 3, 2, 5, 2, 7, 2, 9, 2, 11, 2, 13, 2, 15, 2};
span.Replace(2, 4);
Assert.That(span.ToArray(), Is.EqualTo(new[] {1, 4, 3, 4, 5, 4, 7, 4, 9, 4, 11, 4, 13, 4, 15, 4}));
}
[Test]
public void Replace_ShouldReplaceAllElements_GivenSpanOfChar()
{
Span<char> chars = stackalloc char[12] {'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!'};
chars.Replace('l', 'w');
CollectionAssert.AreEqual(chars.ToArray(), "Hewwo worwd!".ToCharArray());
}
[Test]
public void Replace_ShouldDoNothing_GivenSpanWithNoMatchingElements()
{
Span<int> span = stackalloc int[16] {1, 2, 3, 2, 5, 2, 7, 2, 9, 2, 11, 2, 13, 2, 15, 2};
span.Replace(4, 8);
Assert.That(span.ToArray(), Is.EqualTo(new[] {1, 2, 3, 2, 5, 2, 7, 2, 9, 2, 11, 2, 13, 2, 15, 2}));
}
[Test] [Test]
public void Split_OnEmptySpan_ShouldYieldNothing_UsingCharDelimiter_GivenReadOnlySpan() public void Split_OnEmptySpan_ShouldYieldNothing_UsingCharDelimiter_GivenReadOnlySpan()
{ {

View File

@ -1,4 +1,9 @@
namespace X10D.Collections; #if NET5_0_OR_GREATER
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#endif
namespace X10D.Collections;
/// <summary> /// <summary>
/// Extension methods for <see cref="Span{T}" /> and <see cref="ReadOnlySpan{T}" /> /// Extension methods for <see cref="Span{T}" /> and <see cref="ReadOnlySpan{T}" />
@ -53,6 +58,26 @@ public static class SpanExtensions
return source; return source;
} }
/// <summary>
/// Replaces all occurrences of a specified element in a span of elements with another specified element.
/// </summary>
/// <param name="haystack">The source span.</param>
/// <param name="needle">The element to replace.</param>
/// <param name="replacement">The replacement element.</param>
/// <typeparam name="T">The type of elements in <paramref name="haystack" />.</typeparam>
public static void Replace<T>(this Span<T> haystack, T needle, T replacement) where T : struct
{
var comparer = EqualityComparer<T>.Default;
for (var index = 0; index < haystack.Length; index++)
{
if (comparer.Equals(haystack[index], needle))
{
haystack[index] = replacement;
}
}
}
/// <summary> /// <summary>
/// Splits a span of elements into sub-spans based on a delimiting element. /// Splits a span of elements into sub-spans based on a delimiting element.
/// </summary> /// </summary>