I am trying to use LINQ
to return the an element which occurs maximum number of times AND the number of times it occurs.
For example: I have an array of strings:
string[] words = { "cherry", "apple", "blueberry", "cherry", "cherry", "blueberry" };
//...
Some LINQ statement here
//...
In this array, the query would return cherry
as the maximum occurred element, and 3
as the number of times it occurred. I would also be willing to split them into two queries if that is necessary (i.e., first query to get the cherry
, and second to return the count of 3
.
The solutions presented so far are O(n log n)
. Here's an O(n)
solution:
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
);
This needs a definition of MaxBy
. Here is one:
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;
}
}
var topWordGroup = words.GroupBy(word => word).OrderByDescending(group => group.Count()).FirstOrDefault();
// topWordGroup might be a null!
string topWord = topWordGroup.Key;
int topWordCount = topWordGroup.Count;
And in case if we don't like O(N log N)
:
var topWordGroup = words.GroupBy(word => word).Aggregate((current, acc) => current.Count() < acc.Count() ? acc : current);
First thing that comes to mind (meaning there is probably a more efficient way)
var item = words.GroupBy(x => x).OrderByDescending(x => x.Count()).First()
//item.Key is "cherry", item.Count() is 3
EDIT: forgot op wanted the name and the count
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With