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.