Deal with it or don't

Obvious Methods: Distinct with equality selector

You have an IEnumerable<SomeType> on which you want to do a .Distinct(). “SomeType” is not equatable – at least not in the way you want. Your only choice is to write an IEqualityComparer… Until today!!!

Here’s what you WANT to write:

myEnumerable.Distinct(item => item.Id);

…assuming that the Id’s make them unique. And here’s the extension method override of Distinct that lets you do this:

public static class Extensions


  public static IEnumerable<T> Distinct<T, TCompare>(this IEnumerable<T> items, Func<T, TCompare> predicate)


    var distinctKeys = new HashSet<TCompare>();

    foreach (var item in items)


      var key = predicate(item);

      if (distinctKeys.Contains(key)) continue;


      yield return item;




Now, you’re probably saying, couldn’t I just write?:

myEnumerable.GroupBy(item => item.Id).Select(g => g.First());

It gives you the same output, but, this new Distinct method is:

  1. faster… like an order of magnitude faster
  2. easier to read… like an order of magnitude easier to read.
  3. lazier. Consider the following contrived enumerable:

var list = new[]


              new {x = 1, y = “one”},

              new {x = 1, y = “won”},

              new {x = 1, y = “juan”},

              new {x = 0, y = “zero”},


…and this call to .Distinct:

list.Distinct(item => 1 / item.x).Take(1);

With the GroupBy approach, this would raise an Exception. But with the new Distinct, you get no exception because it is so dang lazy.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s

%d bloggers like this: