C#: Get the Most Common (Mode) Element from a Collection

I was surprised today when I couldn’t find a built in Mode extension method that retrieved the most common or most frequently occurring element in a collection so I set out to write my own. My first approach was to use LINQ to Objects and just group the collection by the individual items, order each group descending by their count, and then return the first element as follows.

public static T Mode<T>(this IEnumerable<T> list)
    // Null testing
    if (list == null || list.Count() == 0)
        return default(T);

    return (from item in list
            group item by item into g
            orderby g.Count() descending
            select g.Key).First();

The above method works great but it left a bad taste in my mouth as ordering the grouped items using LINQ took O(n log n) time and I knew there had to be a way to solve this problem in O(n) time. So, I dropped the LINQ approach and went back to the good ol’ loop. The following method simply traverses the collection and adds an entry for each unique element in the collection into a Dictionary. The value of each Dictionary entry is incremented every time an element is encountered. Then we traverse the Dictionary to find the element with highest value.

/// <summary>
/// Gets the element that occurs most frequently in the collection.
/// </summary>
/// <param name="list"></param>
/// <returns>Returns the element that occurs most frequently in the collection.
/// If all elements occur an equal number of times, a random element in
/// the collection will be returned.</returns>
public static T Mode<T>(this IEnumerable<T> list)
    // Initialize the return value
    T mode = default(T);

    // Test for a null reference and an empty list
    if (list != null && list.Count() > 0)
        // Store the number of occurences for each element
        Dictionary<T, int> counts = new Dictionary<T, int>();

        // Add one to the count for the occurence of a character
        foreach (T element in list)
            if (counts.ContainsKey(element))
                counts.Add(element, 1);

        // Loop through the counts of each element and find the 
        // element that occurred most often
        int max = 0;

        foreach (KeyValuePair<T, int> count in counts)
            if (count.Value > max)
                // Update the mode
                mode = count.Key;
                max = count.Value;

    return mode;


List<int> ints = new List<int>() { 1, 2, 6, 3, 6, 7, 3, 6, 8, 4, 2, 1, 7, 6 };
int mode = ints.Mode();


// Output
// ------
// 6

After some performance testing on large collections, the second method proved to take about half the time compared to that of the LINQ method. Also note that both methods are created using generic types so this extension method can be used on any collection of any type.

5 Responses to “C#: Get the Most Common (Mode) Element from a Collection”

  1. DavidT Says:

    Hi nick, I found this quite useful although there is a flaw, consider this set/list

    1, 1, 1, 1, 2, 2, 2 ,2

    • Nick Olsen Says:

      I guess the result in that situation would be defined by what the logic of the application. Technically there isn’t an element that occurs more often than any other element in the series. But, in that case do you want to return nothing or both 1 and 2? That probably depends on the application.

  2. C#: Get the most common elements (Mode(s)) from a set or List « David Thompson's Blog Says:

    […] writing this post after reading Nick Olsen’s post on the same subject but his piece was about finding the mode from a uni-modal collection (a set […]

  3. duckem Says:

    Hi Nick,
    I just wanted to say thanks for the the code sample. I hope it’s alright I’m using it for a stats application!

    • Nick Olsen Says:

      No problem. Glad it helped!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: