15

How to get the most common value in an Int array using C#

eg: Array has the following values: 1, 1, 1, 2

Ans should be 1

7
  • Is there a restriction on the domain of your integer values? IE. are all of the values between 0 and 10? Commented Apr 16, 2010 at 20:46
  • @Michael Petito: Yeah. If the range is not too big, it can be done really quick. Commented Apr 16, 2010 at 20:50
  • all int will be positive and value not greater than 5 Commented Apr 16, 2010 at 20:50
  • i thought that there is a function like .Average() or .Max() Commented Apr 16, 2010 at 20:51
  • @mouthpiece, those are extensions available via IEnumerable<T>, but they are not applicable here. Average or Max wouldn't give you the most common element, merely the average value or the highest value. Commented Apr 16, 2010 at 20:53

6 Answers 6

29
var query = (from item in array
        group item by item into g
        orderby g.Count() descending
        select new { Item = g.Key, Count = g.Count() }).First();

For just the value and not the count, you can do

var query = (from item in array
                group item by item into g
                orderby g.Count() descending
                select g.Key).First();

Lambda version on the second:

var query = array.GroupBy(item => item).OrderByDescending(g => g.Count()).Select(g => g.Key).First();
Sign up to request clarification or add additional context in comments.

3 Comments

Isn't this doing O(nlogn) sorting?
@liori: Yes. Sorting isn't the most efficient way of finding the highest count.
I'd prefer .First().Key to using that Select myself.
15

Some old fashioned efficient looping:

var cnt = new Dictionary<int, int>();
foreach (int value in theArray) {
   if (cnt.ContainsKey(value)) {
      cnt[value]++;
   } else {
      cnt.Add(value, 1);
   }
}
int mostCommonValue = 0;
int highestCount = 0;
foreach (KeyValuePair<int, int> pair in cnt) {
   if (pair.Value > highestCount) {
      mostCommonValue = pair.Key;
      highestCount = pair.Value;
   }
}

Now mostCommonValue contains the most common value, and highestCount contains how many times it occured.

2 Comments

+1 Nothing wrong with busting out the elbow grease and getting it done.
That second part could be simplified by using MaxBy(). Too bad it's not actually in LINQ (but it is in MoreLinq).
4

I know this post is old, but someone asked me the inverse of this question today.

LINQ Grouping

sourceArray.GroupBy(value => value).OrderByDescending(group => group.Count()).First().First();

Temp Collection, similar to Guffa's:

var counts = new Dictionary<int, int>();
foreach (var i in sourceArray)
{
    if (!counts.ContainsKey(i)) { counts.Add(i, 0); }
    counts[i]++;
}
return counts.OrderByDescending(kv => kv.Value).First().Key;

Comments

2
  public static int get_occure(int[] a)
    {
        int[] arr = a;
        int c = 1, maxcount = 1, maxvalue = 0;
        int result = 0;
        for (int i = 0; i < arr.Length; i++)
        {
            maxvalue = arr[i];
            for (int j = 0; j <arr.Length; j++)
            {

                if (maxvalue == arr[j] && j != i)
                {
                    c++;
                    if (c > maxcount)
                    {
                        maxcount = c;
                        result = arr[i];

                    }
                }
                else
                {
                    c=1;

                }

            }


        }
        return result;
    }

Comments

1

Maybe O(n log n), but fast:

sort the array a[n]

// assuming n > 0
int iBest = -1;  // index of first number in most popular subset
int nBest = -1;  // popularity of most popular number
// for each subset of numbers
for(int i = 0; i < n; ){
  int ii = i; // ii = index of first number in subset
  int nn = 0; // nn = count of numbers in subset
  // for each number in subset, count it
  for (; i < n && a[i]==a[ii]; i++, nn++ ){}
  // if the subset has more numbers than the best so far
  // remember it as the new best
  if (nBest < nn){nBest = nn; iBest = ii;}
}

// print the most popular value and how popular it is
print a[iBest], nBest

2 Comments

You didn't say sort the array at first :). Anyway, you can do this simpler if you're going to sort. One for loop and a few variables should be enough.
@IVlad: wasn't that the first line of code? Anyway, you're right.
1

Yet another solution with linq:

static int[] GetMostCommonIntegers(int[] nums)
{
    return nums
            .ToLookup(n => n)
            .ToLookup(l => l.Count(), l => l.Key)
            .OrderBy(l => l.Key)
            .Last() 
            .ToArray();
}   

This solution can handle case when several numbers have the same number of occurences:

[1,4,5,7,1] => [1]
[1,1,2,2,3,4,5] => [1,2]
[6,6,6,2,2,1] => [6]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.