The Darkside

Shedding light on things and stuff

 
  Home :: Contact :: Syndication  :: Login
  75 Posts :: 0 Stories :: 49 Comments :: 2 Trackbacks

Ads

Archives

Post Categories

Open Source Projects

Other Blogs

Let’s say you’ve got a list of country names that came from a data source that you are not in control of. The list returned looks like this:

USA, South Africa, Australia, United Kingdom, Australia

Yes, Australia is repeated (on purpose). What you’d most likely do with LINQ is:

var countries = (new List<string>() {"USA", "South Africa", "Australia", "United Kingdom", "Australia"}).Distinct();

...and your duplicate is removed. But what if the list you received was like this:

USA, South Africa, Australia, United Kingdom, AUSTRALIA

The code above would not help in this case. There is, however, an override for the Distinct method that allows you to pass your own implementation of IEqualityComparer<> in. In this case, you’d need a comparer that does case insensitive evaluation. I’ve implemented a simple class for this:

 Expand Code

internal class CaseInsensitiveStringComparer : IEqualityComparer<string>

{

    public bool Equals(string x, string y)

    {

        return x.Equals(y, StringComparison.InvariantCultureIgnoreCase);

    }

 

    public int GetHashCode(string obj)

    {

        return obj.ToLower().GetHashCode();

    }

}

You can then modify the original line to look like this:

var countries = (new List<string>() {"USA", "South Africa", "Australia", "United Kingdom", "Australia"}).Distinct(new CaseInsensitiveStringComparer());

and you’d once again have a list of distinct items.

This comparer can also be used for the other set operators (UNION, EXCEPT, INTERSECT). An example of using it for the Except method would be:

var allCountries = new List<string>() {"USA", "South Africa", "United Kingdom", "Australia"};

var notAllowedCountries = new List<string>() { "AUSTRALIA"};

var allowedCountries = allCountries.Except(notAllowedCountries, new CaseInsensitiveStringComparer());

The results variable would now only have 3 items in the list because of the comparer used.

posted on Thursday, August 21, 2008 7:18 AM

Feedback

# re: Using custom comparers in linq set operators 8/28/2008 8:47 AM Darksider
In case anyone wondered why I compared the two strings using:
return x.Equals(y, StringComparison.InvariantCultureIgnoreCase);
you can have a look here for a good explanation on fast string comparisons.

Comments have been closed on this topic.