mirror of
https://github.com/oliverbooth/X10D
synced 2024-11-22 19:28:48 +00:00
Add CountSubstring
This commit is contained in:
parent
3847d53120
commit
9cce13727d
@ -28,10 +28,16 @@
|
||||
- X10D: Added `PointF.ToSizeF()`
|
||||
- X10D: Added `PointF.ToVector2()` for .NET < 6
|
||||
- X10D: Added `PopCount()` for built-in integer types
|
||||
- X10D: Added `ReadOnlySpan<char>.CountSubstring(char)`
|
||||
- X10D: Added `ReadOnlySpan<char>.CountSubstring(ReadOnlySpan<char>[, StringComparison])`
|
||||
- X10D: Added `RoundUpToPowerOf2()` for built-in integer types
|
||||
- X10D: Added `Size.ToPoint()`
|
||||
- X10D: Added `Size.ToPointF()`
|
||||
- X10D: Added `Size.ToVector2()`
|
||||
- X10D: Added `Span<char>.CountSubstring(char)`
|
||||
- X10D: Added `Span<char>.CountSubstring(Span<char>[, StringComparison])`
|
||||
- X10D: Added `string.CountSubstring(char)`
|
||||
- X10D: Added `string.CountSubstring(string[, StringComparison])`
|
||||
- X10D: Added `Quaternion.Multiply(Vector3)` - this functions as an equivalent to Unity's `Quaternion * Vector3` operator
|
||||
- X10D: Added `Vector2.Deconstruct()`
|
||||
- X10D: Added `Vector2.IsOnLine(LineF)`, `Vector2.IsOnLine(PointF, PointF)`, and `Vector2.IsOnLine(Vector2, Vector2)`
|
||||
|
@ -101,6 +101,55 @@ public class StringTests
|
||||
Assert.ThrowsException<ArgumentNullException>(() => "Hello World".ChangeEncoding(Encoding.UTF8, null!));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CountSubstring_ShouldHonor_StringComparison()
|
||||
{
|
||||
Assert.AreEqual(0, "Hello World".CountSubstring('E'));
|
||||
Assert.AreEqual(0, "Hello World".CountSubstring("E"));
|
||||
Assert.AreEqual(1, "Hello World".CountSubstring("E", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.AreEqual(0, "Hello World".AsSpan().CountSubstring('E'));
|
||||
Assert.AreEqual(1, "Hello World".AsSpan().CountSubstring("E".AsSpan(), StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CountSubstring_ShouldReturn0_GivenNoInstanceChar()
|
||||
{
|
||||
Assert.AreEqual(0, "Hello World".CountSubstring('z'));
|
||||
Assert.AreEqual(0, "Hello World".CountSubstring("z"));
|
||||
Assert.AreEqual(0, "Hello World".CountSubstring("z", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.AreEqual(0, "Hello World".AsSpan().CountSubstring('z'));
|
||||
Assert.AreEqual(0, "Hello World".AsSpan().CountSubstring("z".AsSpan(), StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CountSubstring_ShouldReturn1_GivenSingleInstanceChar()
|
||||
{
|
||||
Assert.AreEqual(1, "Hello World".CountSubstring('e'));
|
||||
Assert.AreEqual(1, "Hello World".CountSubstring("e"));
|
||||
Assert.AreEqual(1, "Hello World".CountSubstring("e", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.AreEqual(1, "Hello World".AsSpan().CountSubstring('e'));
|
||||
Assert.AreEqual(1, "Hello World".AsSpan().CountSubstring("e".AsSpan(), StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CountSubstring_ShouldReturn0_GivenEmptyHaystack()
|
||||
{
|
||||
Assert.AreEqual(0, string.Empty.CountSubstring('\0'));
|
||||
Assert.AreEqual(0, string.Empty.CountSubstring(string.Empty));
|
||||
Assert.AreEqual(0, string.Empty.CountSubstring(string.Empty, StringComparison.OrdinalIgnoreCase));
|
||||
Assert.AreEqual(0, string.Empty.AsSpan().CountSubstring('\0'));
|
||||
Assert.AreEqual(0, string.Empty.AsSpan().CountSubstring(string.Empty.AsSpan(), StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CountSubstring_ShouldThrow_GivenNullHaystack()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => ((string?)null!).CountSubstring('\0'));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => ((string?)null!).CountSubstring(string.Empty));
|
||||
Assert.ThrowsException<ArgumentNullException>(() =>
|
||||
((string?)null!).CountSubstring(string.Empty, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void EnumParse_ShouldReturnCorrectValue_GivenString()
|
||||
{
|
||||
|
@ -162,6 +162,159 @@ public static class StringExtensions
|
||||
return value.GetBytes(sourceEncoding).ToString(destinationEncoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Counts the occurrences of a character within the current character span.
|
||||
/// </summary>
|
||||
/// <param name="haystack">The haystack search space.</param>
|
||||
/// <param name="needle">The character to count.</param>
|
||||
/// <returns>An integer representing the count of <paramref name="needle" /> inside <paramref name="haystack" />.</returns>
|
||||
public static int CountSubstring(this Span<char> haystack, char needle)
|
||||
{
|
||||
return CountSubstring((ReadOnlySpan<char>)haystack, needle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Counts the occurrences of a character within the current character span.
|
||||
/// </summary>
|
||||
/// <param name="haystack">The haystack search space.</param>
|
||||
/// <param name="needle">The character to count.</param>
|
||||
/// <returns>An integer representing the count of <paramref name="needle" /> inside <paramref name="haystack" />.</returns>
|
||||
public static int CountSubstring(this ReadOnlySpan<char> haystack, char needle)
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
for (var index = 0; index < haystack.Length; index++)
|
||||
{
|
||||
if (haystack[index] == needle)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Counts the occurrences of a character within the current string.
|
||||
/// </summary>
|
||||
/// <param name="haystack">The haystack search space.</param>
|
||||
/// <param name="needle">The character to count.</param>
|
||||
/// <returns>An integer representing the count of <paramref name="needle" /> inside <paramref name="haystack" />.</returns>
|
||||
public static int CountSubstring(this string haystack, char needle)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
ArgumentNullException.ThrowIfNull(haystack);
|
||||
#else
|
||||
if (haystack is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(haystack));
|
||||
}
|
||||
#endif
|
||||
|
||||
return haystack.AsSpan().CountSubstring(needle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Counts the occurrences of a substring within the current character span.
|
||||
/// </summary>
|
||||
/// <param name="haystack">The haystack search space.</param>
|
||||
/// <param name="needle">The character span to count.</param>
|
||||
/// <returns>An integer representing the count of <paramref name="needle" /> inside <paramref name="haystack" />.</returns>
|
||||
public static int CountSubstring(this ReadOnlySpan<char> haystack, ReadOnlySpan<char> needle)
|
||||
{
|
||||
return CountSubstring(haystack, needle, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Counts the occurrences of a substring within the current character span, using a specified string comparison method.
|
||||
/// </summary>
|
||||
/// <param name="haystack">The haystack search space.</param>
|
||||
/// <param name="needle">The character span to count.</param>
|
||||
/// <param name="comparison">The string comparison method used for determining substring count.</param>
|
||||
/// <returns>An integer representing the count of <paramref name="needle" /> inside <paramref name="haystack" />.</returns>
|
||||
public static int CountSubstring(this ReadOnlySpan<char> haystack, ReadOnlySpan<char> needle, StringComparison comparison)
|
||||
{
|
||||
if (haystack.IsEmpty || needle.IsEmpty)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int haystackLength = haystack.Length;
|
||||
int needleLength = needle.Length;
|
||||
var count = 0;
|
||||
|
||||
for (var index = 0; index < haystackLength - needleLength - 1; index++)
|
||||
{
|
||||
if (haystack[index..(index + needleLength)].Equals(needle, comparison))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Counts the occurrences of a substring within the current character span.
|
||||
/// </summary>
|
||||
/// <param name="haystack">The haystack search space.</param>
|
||||
/// <param name="needle">The character span to count.</param>
|
||||
/// <returns>An integer representing the count of <paramref name="needle" /> inside <paramref name="haystack" />.</returns>
|
||||
public static int CountSubstring(this Span<char> haystack, Span<char> needle)
|
||||
{
|
||||
return CountSubstring(haystack, needle, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Counts the occurrences of a substring within the current character span, using a specified string comparison method.
|
||||
/// </summary>
|
||||
/// <param name="haystack">The haystack search space.</param>
|
||||
/// <param name="needle">The character span to count.</param>
|
||||
/// <param name="comparison">The string comparison method used for determining substring count.</param>
|
||||
/// <returns>An integer representing the count of <paramref name="needle" /> inside <paramref name="haystack" />.</returns>
|
||||
public static int CountSubstring(this Span<char> haystack, Span<char> needle, StringComparison comparison)
|
||||
{
|
||||
return CountSubstring((ReadOnlySpan<char>)haystack, needle, comparison);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Counts the occurrences of a substring within the current string.
|
||||
/// </summary>
|
||||
/// <param name="haystack">The haystack search space.</param>
|
||||
/// <param name="needle">The substring to count.</param>
|
||||
/// <returns>An integer representing the count of <paramref name="needle" /> inside <paramref name="haystack" />.</returns>
|
||||
public static int CountSubstring(this string haystack, string? needle)
|
||||
{
|
||||
return CountSubstring(haystack, needle, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Counts the occurrences of a substring within the current string, using a specified string comparison method.
|
||||
/// </summary>
|
||||
/// <param name="haystack">The haystack search space.</param>
|
||||
/// <param name="needle">The substring to count.</param>
|
||||
/// <param name="comparison">The string comparison method used for determining substring count.</param>
|
||||
/// <returns>An integer representing the count of <paramref name="needle" /> inside <paramref name="haystack" />.</returns>
|
||||
public static int CountSubstring(this string haystack, string? needle, StringComparison comparison)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
ArgumentNullException.ThrowIfNull(haystack);
|
||||
#else
|
||||
if (haystack is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(haystack));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (string.IsNullOrWhiteSpace(needle))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return haystack.AsSpan().CountSubstring(needle, comparison);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a <see cref="string" /> into an <see cref="Enum" />.
|
||||
/// </summary>
|
||||
|
Loading…
Reference in New Issue
Block a user