BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

LINQ
.NET 3.5+

A LINQ Style Mode Operator

Language Integrated Query (LINQ) includes the Average operator that can be used to calculate the mean value of a sequence. This article implements a LINQ operator that determines the mode, which is the most common value or group of values.

Creating the Overloads

In many situations you will not want to provide a projection function or a customer comparer. To make the Mode operator easier to use, we'll add three overloaded versions, each calling the main method. The first removes the need to provide a selector function. A default selector of "s => s" means that the values used when determining the mode will be those from the source sequence. Note that we now only have one type parameter as both the input and output sequences are of the same type.

public static IEnumerable<T> Mode<T>(
    this IEnumerable<T> source, IEqualityComparer<T> comparer)
{
    return source.Mode(s => s, comparer);
}

The next overload removes the comparer. The method calls the initial overload, passing null to the comparer. The main method will capture the null and use the default comparer:

public static IEnumerable<T> Mode<T, R>(this IEnumerable<T> source, Func<T, R> selector)
{
    return source.Mode(selector, null);
}

Finally, we can remove the selector and the comparer, allowing the extension method to be called without parameters:

public static IEnumerable<T> Mode<T>(this IEnumerable<T> source)
{
    return source.Mode(s => s, null);
}

Testing the Method

We can now try calling the various overloaded versions of the method.

var mode1 = new float[] { 1, 1, 2, 2, 2, 3, 4, 4, 4, 5 }.Mode();
// 2, 4

var mode2 = new string[] { "One", "one", "Two", "two", "Three" }.Mode();
// "One", "one", "Two", "two", "Three"

var mode3 = new string[] { "One", "one", "two", "Two", "Three" }.Mode(
    StringComparer.OrdinalIgnoreCase);
// "One", "two"

var mode4 = new string[] { "One", "one", "two", "Two", "Three" }.Mode(s => s.Length);
// 3

var mode5 = new int[] { }.Mode();
// Empty sequence
18 May 2011