Учитывая следующий простой пример:
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();
Похоже, что CaseInsensitiveComparer фактически не используется для сравнения без учета регистра.
Другими словами distinctList содержит то же количество элементов, что и list. Вместо этого я бы ожидал, что, например, "Три" и "Три" считаются равными.
Я что-то упустил или это проблема с оператором Distinct?
Ответ 1
StringComparer
делает то, что вам нужно:
List<string> list = new List<string>() {
"One", "Two", "Three", "three", "Four", "Five" };
var distinctList = list.Distinct(
StringComparer.CurrentCultureIgnoreCase).ToList();
(или инвариантный/порядковый/и т.д. в зависимости от данных, которые вы сравниваете)
Ответ 2
[См. Marc Gravells, если вы хотите наиболее сжатый подход]
После некоторого расследования и хорошей обратной связи от Брэдли Грейнджера я внедрил следующий IEqualityComparer. Он поддерживает нечувствительность к регистру Distinct() (просто передайте экземпляр этого оператора Distinct):
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
}
Ответ 3
Вот более простая версия.
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();
Ответ 4
## 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 будет
USA
INDIA
UK