Reputation: 62145
Given the following simple example:
List<string> list = new List<string>() { "One", "Two", "Three", "three", "Four", "Five" };
CaseInsensitiveComparer ignoreCaseComparer = new CaseInsensitiveComparer();
var distinctList = list.Distinct(ignoreCaseComparer as IEqualityComparer<string>).ToList();
It appears the CaseInsensitiveComparer is not actually being used to do a case-insensitive comparison.
In other words distinctList contains the same number of items as list. Instead I would expect, for example, "Three" and "three" be considered equal.
Am I missing something or is this an issue with the Distinct operator?
Upvotes: 126
Views: 53006
Reputation: 51
## Distinct Operator( Ignoring Case) ##
string[] countries = {"USA","usa","INDIA","UK","UK" };
var result = countries.Distinct(StringComparer.OrdinalIgnoreCase);
foreach (var v in result)
{
Console.WriteLine(v);
}
OutPut will Be
USA
INDIA
UK
Upvotes: 5
Reputation: 62145
[See Marc Gravells answer if you want the most concise approach]
After some investigation and good feedback from Bradley Grainger I've implemented the following IEqualityComparer. It suports a case insensitive Distinct() statement (just pass an instance of this to the Distinct operator) :
class IgnoreCaseComparer : IEqualityComparer<string> { public CaseInsensitiveComparer myComparer; public IgnoreCaseComparer() { myComparer = CaseInsensitiveComparer.DefaultInvariant; } public IgnoreCaseComparer(CultureInfo myCulture) { myComparer = new CaseInsensitiveComparer(myCulture); } #region IEqualityComparer<string> Members public bool Equals(string x, string y) { if (myComparer.Compare(x, y) == 0) { return true; } else { return false; } } public int GetHashCode(string obj) { return obj.ToLower().GetHashCode(); } #endregion }
Upvotes: 5
Reputation:
Here is a far simpler version.
List<string> list = new List<string>() { "One", "Two", "Three", "three", "Four", "Five" };
var z = (from x in list select new { item = x.ToLower()}).Distinct();
z.Dump();
Upvotes: 0
Reputation: 1063864
StringComparer
does what you need:
List<string> list = new List<string>() {
"One", "Two", "Three", "three", "Four", "Five" };
var distinctList = list.Distinct(
StringComparer.CurrentCultureIgnoreCase).ToList();
(or invariant / ordinal / etc depending on the data you are comparing)
Upvotes: 294