Оператор LINQ Distinct, игнорировать случай?



учитывая следующий простой пример:



    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 содержит то же количество элементов, что и список. Вместо этого я ожидал бы, например, что "три" и "три" будут считаться равными.



Я что-то упустил или это проблема с отдельным оператором?

599   4  

4 ответов:

StringComparer что нужно:

List<string> list = new List<string>() {
    "One", "Two", "Three", "three", "Four", "Five" };

var distinctList = list.Distinct(
    StringComparer.CurrentCultureIgnoreCase).ToList();

(или инвариантный / порядковый / etc в зависимости от данных, которые вы сравниваете)

[см. ответ Марка Гравелса, если вы хотите самый краткий подход]

после некоторого исследования и хорошей обратной связи от Брэдли Грейнджера я реализовал следующий 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
}

вот гораздо более простая версия.

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();

 ## 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);
  }

выход будет

   USA 
   INDIA
   UK

Comments

    Ничего не найдено.