我正在尝试使用LINQ
来返回最多次出现的元素及其出现的次数。
例如: 我有一个字符串数组:
string[] words = { "cherry", "apple", "blueberry", "cherry", "cherry", "blueberry" };
//...
Some LINQ statement here
//...
在此数组中,查询将返回cherry
作为最大发生元素,并3
作为发生的次数。如果有必要,我也愿意将它们分成两个查询( ie,第一个查询获取cherry
,第二个返回3
的数量。 / p>
答案 0 :(得分:12)
到目前为止提出的解决方案是O(n log n)
。这是一个O(n)
解决方案:
var max = words.GroupBy(w => w)
.Select(g => new { Word = g.Key, Count = g.Count() })
.MaxBy(g => g.Count);
Console.WriteLine(
"The most frequent word is {0}, and its frequency is {1}.",
max.Word,
max.Count
);
这需要MaxBy
的定义。这是一个:
public static TSource MaxBy<TSource>(
this IEnumerable<TSource> source,
Func<TSource, IComparable> projectionToComparable
) {
using (var e = source.GetEnumerator()) {
if (!e.MoveNext()) {
throw new InvalidOperationException("Sequence is empty.");
}
TSource max = e.Current;
IComparable maxProjection = projectionToComparable(e.Current);
while (e.MoveNext()) {
IComparable currentProjection = projectionToComparable(e.Current);
if (currentProjection.CompareTo(maxProjection) > 0) {
max = e.Current;
maxProjection = currentProjection;
}
}
return max;
}
}
答案 1 :(得分:8)
var topWordGroup = words.GroupBy(word => word).OrderByDescending(group => group.Count()).FirstOrDefault();
// topWordGroup might be a null!
string topWord = topWordGroup.Key;
int topWordCount = topWordGroup.Count;
如果我们不喜欢O(N log N)
:
var topWordGroup = words.GroupBy(word => word).Aggregate((current, acc) => current.Count() < acc.Count() ? acc : current);
答案 2 :(得分:4)
首先想到的是(意味着可能有更有效的方式)
var item = words.GroupBy(x => x).OrderByDescending(x => x.Count()).First()
//item.Key is "cherry", item.Count() is 3
编辑:忘了我想要名字和计数
答案 3 :(得分:1)
string[] words = { "cherry", "apple", "blueberry", "cherry", "cherry", "blueberry" };
var topWordAndCount=words
.GroupBy(w=>w)
.OrderByDescending(g=>g.Count())
.Select(g=>new {Word=g.Key,Count=g.Count()})
.FirstOrDefault();
//if(topWordAndCount!=null)
//{
// topWordAndCount.Word
// topWordAndCount.Count
答案 4 :(得分:0)
答案 5 :(得分:0)
string[] words = { "cherry", "apple", "blueberry", "cherry", "cherry", "blueberry" };
var r = words.GroupBy (x => x)
.OrderByDescending (g => g.Count ())
.FirstOrDefault ();
Console.WriteLine (String.Format ("The element {0} occurs {1} times.", r.Key, r.Count ()));
答案 6 :(得分:0)
更简单的O(n)解决方案:
var groups = words.GroupBy(x => x);
var max = groups.Max(x => x.Count());
var top = groups.First(y => y.Count() == max).Key;
答案 7 :(得分:0)
这是一行(!)中非常快速的O(n)解决方案:
s.GroupBy(x => x).Aggregate((IGrouping<string,string>)null, (x, y) => (x != null && y != null && x.Count() >= y.Count()) || y == null ? x : y, x => x);
或者这个:
s.GroupBy(x => x).Select(x => new { Key = x.Key, Count = x.Count() }).Aggregate(new { Key = "", Count = 0 }, (x, y) => x.Count >= y.Count ? x : y, x => x);