首先,让我们将字符串投影到具有匹配数的序列中:
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();
}
然而有一个很大的HOWEVER。在 C# 中你调用什么char
不是你们用你们的语言所说的性格。这在其他帖子中已被广泛讨论,例如:将大文本分割成小块的最快方法 and 如何执行 Unicode 感知的逐个字符比较?那我就不在这里重复一切了。要“意识到 Unicode”,您需要使代码更加复杂(请注意代码是在此处编写的,然后未经测试):
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();
正如您现在可以想象的那样,这种比较不仅限于某些esoteric语言,但它也适用于不变区域性(en-US),那么对于必须始终与不变区域性进行比较的字符串,您应该指定StringComparison.InvariantCulture
。不要忘记您可能需要致电String.Normalize()
也用于输入字符。