tags:

views:

405

answers:

3

Is there a quick and nice way with lambda expressions?

+17  A: 

How about:

var most = list.GroupBy(i=>i).OrderByDescending(grp=>grp.Count())
      .Select(grp=>grp.Key).First();

or in query syntax:

var most = (from i in list
            group i by i into grp
            orderby grp.Count() descending
            select grp.Key).First();

Of course, if you will use this repeatedly, you could add an extension method:

public static T MostCommon<T>(this IEnumerable<T> list)
{
    return ... // previous code
}

Then you can use:

var most = list.MostCommon();
Marc Gravell
Thats what I was trying to get at, but my brain just ain't working at the moment.
Nathan W
What if more than one element is the answer?
Varun Mahajan
@Varun - good question; but it isn't hard to adapt to suit
Marc Gravell
+2  A: 

Not sure about the lambda expressions, but I would

  1. Sort the list [O(n log n)]

  2. Scan the list [O(n)] finding the longest run-length.

  3. Scan it again [O(n)] reporting each number having that run-length.

This is because there could be more than one most-occurring number.

Mike Dunlavey
A: 

Someone asked for a solution where there's ties. Here's a stab at that:

int indicator = 0

var result =
  list.GroupBy(i => i)
    .Select(g => new {i = g.Key, count = g.Count()}
    .OrderByDescending(x => x.count)
    .TakeWhile(x =>
    {
      if (x.count == indicator || indicator == 0)
      {
        indicator = x.count;
        return true;
      }
      return false;
    })
    .Select(x => x.i);
David B