簡體   English   中英

C#等價於C ++ std :: string find_first_not_of和find_last_not_of

[英]C# equivalent of C++ std::string find_first_not_of and find_last_not_of

IndexOfIndexOfAnyLastIndexOfLastIndexOfAny似乎沒有這些(或者他們可能會這樣做)。 我正在尋找std :: string的find_first_not_offind_last_not_offind_first_not_of find_last_not_of 我正在考慮創建一個擴展類,但我不確定C#是否已經提供了這個功能。

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();

或者,如果您更喜歡一些非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;
}

(你可能會在LINQ和非LINQ版本中獲得更好的性能 - 如果你將chars轉換為HashSet<char> ,或者甚至是一個普通的char[]數組。你需要進行基准測試發現,雖然任何差異可能是微不足道的,除非chars變得很大。)

如果可以使用LINQ,則可以使用適當的謂詞調用First()Last()方法。

例如,如果您想要不是元音的第一個和最后一個字符:

string vowels = "aeiouy";
char first = yourString.First(ch => vowels.IndexOf(ch) < 0);
char last = yourString.Last(ch => vowels.IndexOf(ch) < 0);

編輯:上面將返回字符,而不是它們的索引。 為了做到這一點,你可以使用Select()方法來設計索引,但事情會變得毛茸茸,因為如果沒有字符匹配我們需要返回-1

int firstIndex = (yourString.Select(
        (ch, i) => new { Character = ch, Index = i }
    ).First(obj => vowels.IndexOf(obj.Character) < 0)
    ?? new { Character = '\0', Index = -1 }).Index;

int lastIndex = (yourString.Select(
        (ch, i) => new { Character = ch, Index = i }
    ).Last(obj => vowels.IndexOf(obj.Character) < 0)
    ?? new { Character = '\0', Index = -1 }).Index;

或者,根據@ abatishchev的答案,這是一個不太復雜的解決方案:

string vowels = "aeiouy";
int firstIndex = yourString.IndexOf(yourString.First(
    ch => vowels.IndexOf(ch) < 0));
int lastIndex = yourString.LastIndexOf(yourString.Last(
    ch => vowels.IndexOf(ch) < 0));

這是一個正則表達式解決方案。

string testString = "oueytestie";
var matchFirstNotOf = Regex.Match(testString, @"[^aeiouy]");
int firstNotOf = matchFirstNotOf.Success ? matchFirstNotOf.Index : -1;
var matchLastNotOf = Regex.Match(testString, @"[^aeiouy]", RegexOptions.RightToLeft);
int lastNotOf = matchLastNotOf.Success ? matchLastNotOf.Index : -1;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM