Find the most frequent numbers in an array using LINQ

List<int> a = new List<int>{ 1,1,2,2,3,4,5 };

What is the fastest way to do this using LINQ?

I'm new to LINQ

+2
source share
5 answers

The key here is Enumerable.GroupBythe aggregation method Enumerable.Count:

List<int> list = new List<int>() { 1,1,2,2,3,4,5 };

// group by value and count frequency
var query = from i in list
            group i by i into g
            select new {g.Key, Count = g.Count()};

// compute the maximum frequency
int whatsTheFrequencyKenneth = query.Max(g => g.Count);

// find the values with that frequency
IEnumerable<int> modes = query
                              .Where(g => g.Count == whatsTheFrequencyKenneth)
                              .Select(g => g.Key);

// dump to console
foreach(var mode in modes) {
    Console.WriteLine(mode);
}
+17
source

Jason's answer is correct, but you can perform this operation in a single LINQ operation.

        List<int> list = new List<int>() { 1, 1, 2, 2, 3, 4, 5 };

        // return most frequently occurring items
        var query = from i in list
                    group i by i into g

                    let maxFreq = (from i2 in list 
                                  group i2 by i2 into g2
                                  orderby g2.Count() descending 
                                  select g2.Count()).First() 

                    let gCount = g.Count()

                    where gCount == maxFreq 

                    select  g.Key;

        // dump to console
        foreach (var mode in query)
        {
            Console.WriteLine(mode);
        }
+3
source
public static Tres MostCommon<Tsrc, Tres>(this IEnumerable<Tsrc> source, Func<Tsrc, Tres> transform)
{
    return source.GroupBy(s => transform(s)).OrderByDescending(g => g.Count()).First().Key;
}

And in your example with built-in types, you can call it like:

List<int> a = new List<int>{ 1,1,2,2,3,4,5 };
int mostCommon = a.MostCommon(x => x);
+2
source
from num in a
group num by num into numg
let c = numg.Count()
order by c descending
select new { Number = numg.Key, Count = c }
+1
source

I think the most frequent number can also be reached in a single query like this -

  var query = (from i in list
               group i by i into g
               orderby g.Count() descending
               select new { Key = g.Key, Count = g.Count() }).FirstOrDefault();
  if (query == null) Console.WriteLine("query = NULL");
  else  Console.WriteLine("The number '{0}' occurs {1} times.", query.Key, query.Count);

Zero checking is not really required, but can be useful when zero is actually expected (for example, an empty list?)

0
source

All Articles