首先,讓我們伸出你的字符串與匹配的計數序列:
myStrings.Select(x => x.Count(x => x == '#')) // {1, 2, 6} in your example
然後拿起最大值:
int maximum = myStrings
.Select(s => s.Count(x => x == '#'))
.Max(); // 6 in your example
讓我們做一個擴展方法:
public static int CountMaximumOccurrencesOf(this IEnumerable<string> strings, char ch)
{
return strings
.Select(s => s.Count(c => c == ch))
.Max();
}
但是有一個大的但是。你在C#中調用char
不是你所說的語言中的字符。這已在其他帖子中被廣泛討論,例如:Fastest way to split a huge text into smaller chunks和How can I perform a Unicode aware character by character comparison?,那麼我不會在這裏重複一切。要「統一認識」你需要讓你的代碼更加複雜(請注意代碼寫到這裏那麼它是未經測試):
private static IEnumerable<string> EnumerateCharacters(string s)
{
var enumerator = StringInfo.GetTextElementEnumerator(s.Normalize());
while (enumerator.MoveNext())
yield return (string)enumerator.Value;
}
我們原來的代碼然後更改爲:
public static int CountMaximumOccurrencesOf(this IEnumerable<string> strings, string character)
{
return strings
.Select(s => s.EnumerateCharacters().Count(c => String.Equals(c, character, StringComparison.CurrentCulture))
.Max();
}
注意Max()
單獨要求收集不能爲空(如果收集可能爲空並且不是錯誤,則使用DefaultIfEmpty()
)。要做到不隨意決定如何在這種情況下做的(拋出一個異常,如果它要發生或只返回0),你可以可以使這種方法不太專業的,離開這個責任來電者:
public static int CountOccurrencesOf(this IEnumerable<string> strings,
string character,
StringComparison comparison = StringComparison.CurrentCulture)
{
Debug.Assert(character.EnumerateCharacters().Count() == 1);
return strings
.Select(s => s.EnumerateCharacters().Count(c => String.Equals(c, character, comparison));
}
像這樣來使用:
var maximum = myStrings.CountOccurrencesOf("#").Max();
如果你需要它不區分大小寫:
var maximum = myStrings.CountOccurrencesOf("à", StringComparison.CurrentCultureIgnoreCase)
.Max();
正如你現在能想象這種比較並不侷限於某些深奧語言,但它也適用於不變文化(en-US),那麼對於必須始終與不變文化進行比較的字符串,您應指定StringComparison.InvariantCulture
。不要忘記,您也可能需要撥打String.Normalize()
來輸入字符。
呸,只是打我給它。 – krillgar