C#等价于C++ std :: string find_first_not_of和find_last_not_of

Mar*_*lon 8 c# string

IndexOf,IndexOfAny而且LastIndexOf,LastIndexOfAny似乎没有这些(或者他们可能).我正在寻找std :: string find_first_not_offind_last_not_of.的公差.我正在考虑创建一个扩展类,但我不确定C#是否已经提供了这个功能.

Luk*_*keH 11

string source = "the quick brown fox jumps over the lazy dog";
string chars = "ogd hte";

int? firstNotOf = source.Select((x, i) => new { Val = x, Idx = (int?)i })
                        .Where(x => chars.IndexOf(x.Val) == -1)
                        .Select(x => x.Idx)
                        .FirstOrDefault();

int? lastNotOf = source.Select((x, i) => new { Val = x, Idx = (int?)i })
                       .Where(x => chars.IndexOf(x.Val) == -1)
                       .Select(x => x.Idx)
                       .LastOrDefault();
Run Code Online (Sandbox Code Playgroud)

或者,如果您更喜欢一些非LINQ扩展方法.这些应该有稍微好一点的性能,特别是对于FindLastNotOf:

int? firstNotOf = source.FindFirstNotOf(chars);
int? lastNotof = source.FindLastNotOf(chars);

// ...

public static int? FindFirstNotOf(this string source, string chars)
{
    if (source == null) throw new ArgumentNullException("source");
    if (chars == null) throw new ArgumentNullException("chars");
    if (source.Length == 0) return null;
    if (chars.Length == 0) return 0;

    for (int i = 0; i < source.Length; i++)
    {
        if (chars.IndexOf(source[i]) == -1) return i;
    }
    return null;
}

public static int? FindLastNotOf(this string source, string chars)
{
    if (source == null) throw new ArgumentNullException("source");
    if (chars == null) throw new ArgumentNullException("chars");
    if (source.Length == 0) return null;
    if (chars.Length == 0) return source.Length - 1;

    for (int i = source.Length - 1; i >= 0; i--)
    {
        if (chars.IndexOf(source[i]) == -1) return i;
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

(你可能会在LINQ和非LINQ版本中获得更好的性能 - 如果你转换chars成一个HashSet<char>或者甚至是一个普通的char[]数组.你需要进行基准测试才能发现,尽管可能存在任何差异除非chars变得很大,否则可以忽略不计.)