IndexOf
,IndexOfAny
和LastIndexOf
,LastIndexOfAny
似乎不這樣做(或者可能他們這樣做)。我正在尋找std :: string的find_first_not_of
和find_last_not_of
的equialent。我正在考慮創建一個擴展類,但我不確定C#是否已經提供了這個功能。C#相當於C++ std :: string find_first_not_of和find_last_not_of
回答
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));
不完全:'find_first_not_of'返回位置,而不是字符。 – Vlad 2010-12-21 10:58:55
@Vlad,你是對的,回答相應更新。謝謝:) – 2010-12-21 11:06:22
我認爲,LINQ過分複雜的東西。而這個解決方案是非常無效的。我們與迭代器一起創建了很多匿名類型的臨時對象。對於循環來說簡單的書寫方法會更好。 – 2010-12-21 11:15:29
這是一個正則表達式解決方案。
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;
- 1. C++ std :: string和string
- 2. Cython C++和std :: string
- 3. 使用std :: sscanf和std :: string的C++
- 4. STL相關seg錯誤在C++ std :: string?
- 5. C++循環std :: vector <std :: map <std :: string,std :: string>>
- 6. C/C++相當於C#System.Net.Mail
- 7. std :: string name和std :: string&name之間的C++區別
- 8. 相當於C#
- 9. C#相當於fprintf
- 10. C#相當於pydoc
- 11. C#相當於OBJ-C的
- 12. C#相當於InStrRev
- 13. C#相當於FREAD
- 14. C++的std :: string構造
- 15. C++ /串連的std :: string和WCHAR *至* WCHAR
- 16. C#ULONG_PTR相當於
- 17. C++ std :: string到Ruby VALUE
- 18. C++:的std :: string問題
- 19. C++ std :: string到布爾值
- 20. 在C#中的std :: string?
- 21. C++ const std :: string賦值
- 22. C++相當於tailq
- 23. boost :: format表單c-string或std :: string
- 24. C++/CX:將std :: string轉換爲Platform :: String^
- 25. C-pstree相當於
- 26. httplib相當於C
- 27. strtoul相當於C#
- 28. C++相當於java.lang.Integer.MIN_VALUE
- 29. ungetc相當於c#
- 30. std :: string和stdarg.h
不錯的工作,但是他們正確的頭腦在圖書館或API程序中發現任何可以接受的東西?看起來像一個MS失敗。 – GTAE86 2014-03-28 18:11:13