dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.43k stars 4.76k forks source link

[API Proposal]: ReadOnlySpan<char>.StartsWithAny(SearchValues<string>) and ReadOnlySpan<char>.EndsWithAny(SearchValues<string>) #110115

Open silkfire opened 1 day ago

silkfire commented 1 day ago

Background and motivation

There currently doesn't seem to be a means of checking whether the beginning or the end of a string equals to any of the values contained in a specified set of values in an optimized way using SearchValues<string> that was introduced in .NET 9. There are other specialized extension APIs involving ReadOnlySpan<char> and SearchValues<string> that were recently added (e.g. IndexOfAny<T>(ReadOnlySpan<char>, SearchValues<string>), ContainsAny(ReadOnlySpan<char>, SearchValues<string>) et al.) but this particular API seems to be missing.

One use case could be if you need to efficiently check whether a string starts with any one of a particular set of prefixes in order to determine whether your application code supports or handles that particular item.

See also #94155.

API Proposal

namespace System;

public static class MemoryExtensions
{
    // Proposed
    public static bool StartsWithAny(this System.ReadOnlySpan<char> span, System.Buffers.SearchValues<string> values);
    public static bool EndsWithAny(this System.ReadOnlySpan<char> span, System.Buffers.SearchValues<string> values);
}

API Usage

var searchValues = SearchValues.Create(new[] { "P1", A99", "B44" }.AsSpan(), StringComparison.Ordinal);

var isSupported = "testValue".StartsWithAny(searchValues);
var isSupported2 = "testValue".EndsWithAny(searchValues);

Alternative Designs

N/A

Risks

N/A

dotnet-policy-service[bot] commented 1 day ago

Tagging subscribers to this area: @dotnet/area-system-memory See info in area-owners.md if you want to be subscribed.

MihaZupan commented 20 hours ago

What sort of use cases do you have for EndsWithAny (note that we also didn't expose a LastIndexOfAny for SearchValues<string>)?

silkfire commented 20 hours ago

Good question; I actually wasn't aware of that. I assume StartsWithAny would be more common (and therefore more useful) than EndsWithAny so including the latter one would only be to make the API complete.