Reputation: 7569
I have an array:
string[] myFruits =
{
"apple",
"banana",
"banana",
"orange",
"cherry",
"cherry",
"cherry",
"mango",
"kiwi",
"kiwi",
}
I want a new collection with the 3 most popular fruits, in order. In this example, it would be ["cherry", "banana", "kiwi"]
.
I have been looking at Linq, trying to figure out how to use the GroupBy, OrderByDescending, and Count in some sort of combination to get me the desired results, but I have not been even close to successful.
For example:
var popularFuits = myFruits.GroupBy(f => f).OrderByDescending(f => f.Count).Take(3);
How can I get the most popular n strings from a collection?
Upvotes: 0
Views: 138
Reputation: 14228
You can GroupBy
then OrderByDescending
the number of items in a group like below.
var result = myFruits.GroupBy(p => p)
.OrderByDescending(g => g.Count())
.Take(3);
foreach(var item in result)
Console.WriteLine(item.Key + " " + item.Count());
Output
cherry 3
banana 2
kiwi 2
Upvotes: 0
Reputation: 13364
Your query is almost there.
IGrouping<T>
does not have .Count
property, so you need to use .Count()
extension method.Key
of the group.var popularFuits = myFruits
.GroupBy(f => f)
.OrderByDescending(g => g.Count())
.Select(g => g.Key)
.Take(3) /*.ToList()*/;
Upvotes: 4
Reputation: 6864
The following will give you fruits sorted by popularity and then alphabetically if they're equally popular
var popularFuits = myFruits
.GroupBy(f => f)
.Select(g => new
{
Name = g.Key,
Count = g.Count()
})
.OrderByDescending(f => f.Count)
.ThenBy(f => f.Name)
.Take(3);
foreach (var fruit in popularFuits)
Console.WriteLine($"{fruit.Name} - {fruit.Count}");
OUTPUT
cherry - 3
banana - 2
kiwi - 2
Upvotes: 2