C#中简单的LINQ问题

我试图使用LINQ返回一个发生最大次数的元素及其发生的次数。

例如:我有一个字符串数组:

 string[] words = { "cherry", "apple", "blueberry", "cherry", "cherry", "blueberry" }; //... Some LINQ statement here //... 

在此数组中,查询将返回cherry作为最大发生元素,并返回3作为其发生的次数。 如果有必要我也愿意将它们分成两个查询( 即,第一个查询获取cherry ,第二个返回3计数。

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

到目前为止提出的解决方案是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( this IEnumerable source, Func 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; } } 

首先想到的是(意味着可能有更有效的方式)

 var item = words.GroupBy(x => x).OrderByDescending(x => x.Count()).First() //item.Key is "cherry", item.Count() is 3 

编辑 :忘了操作想要的名字计数

 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 

试试这个:

将包含top,count,group和order的SQL转换为LINQ(2个实体)

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

一个更简单的O(n)解决方案:

 var groups = words.GroupBy(x => x); var max = groups.Max(x => x.Count()); var top = groups.First(y => y.Count() == max).Key; 

这是一行中非常快速的O(n)解决方案(!):

 s.GroupBy(x => x).Aggregate((IGrouping)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);