Finding missing numbers in a list using LINQ with C#



Let’s say you have a list of integer values that represent the days of a month like this:

6, 2, 4, 1, 9, 7, 3, 10, 15, 19, 11, 18, 13, 22, 24, 20, 27, 31, 25, 28

Clearly we have missing numbers/days in the list above. They are:

5 8 12 14 16 17 21 23 26 29 30

It’s really easy to get a list of missing numbers using LINQ with C# and the Except operator. LINQ is the greatest addition to the C# language. I can imagine how life would be difficult if we hadn’t LINQ!

This is how I implemented a missing numbers finder using a C# extension method:

public static class MyExtensions
{
    /// <summary>
    /// Finds the missing numbers in a list.
    /// </summary>
    /// <param name="list">List of numbers</param>
    /// <returns>Missing numbers</returns>
    public static IEnumerable<int> FindMissing(this List<int> list)
    {
        // Sorting the list
        list.Sort();

        // First number of the list
        var firstNumber = list.First();
// Last number of the list var lastNumber = list.Last(); // Range that contains all numbers in the interval
// [ firstNumber, lastNumber ]
var range = Enumerable.Range(firstNumber, lastNumber - firstNumber); // Getting the set difference var missingNumbers = range.Except(list); return missingNumbers; } }

Now you can call the extension method in the following way:

class Program
{
    static void Main(string[] args)
    {
        // List of numbers
        List<int> daysOfMonth =
            new List<int>() { 6, 2, 4, 1, 9, 7, 3, 10, 15, 19, 11, 18, 13, 22, 24, 20, 27, 31, 25, 28 };

        Console.Write("\nList of days: ");

        foreach(var num in daysOfMonth)
        {
            Console.Write("{0} ", num);
        }

        Console.Write("\n\nMissing days are: ");

        // Calling the Extension Method in the List of type int 
foreach(var number in daysOfMonth.FindMissing()) { Console.Write("{0} ", number); } } }

This is the output:

 Missing Numbers Finder output

In this simple program I’m using 3 concepts of the C# language that are really interesting: implicitly typed local variables, extension methods and collection initializers.

Hope this simple extension method to find the missing elements of a sequence helps the developers out there.

Visual Studio 2008 C# Console Application
You can get the Microsoft Visual Studio Project at:

http://leniel.googlepages.com/MissingNumbersFinder.zip

To try out the code you can use the free Microsoft Visual C# 2008 Express Edition that you can get at: http://www.microsoft.com/express/vcsharp/

3 comments:

Anonymous said...

Hi, why not use 'T' instead of 'int' ? it would make it generic...

David Bilbey said...

Of course, this solution assumes that the list you use already contains the first and last days of the range....

Leniel Macaferi said...

Hi Anonymous,

It's not so easy to do arithmetic with a generic type T in C#. Moreover I don't see much use for it in this case.

See this link: http://stackoverflow.com/questions/1348594/is-there-a-c-generic-constraint-for-real-number-types

Enumerable.Range is restricted to int values. If you wanted to use long you could use something like this: http://srtsolutions.com/blogs/chrismarinos/archive/2009/02/12/beyond-linq-sequence-generation-in-c.aspx

All the best,

Leniel Macaferi

Post a Comment