LINQ Distinct operatörü, büyük / küçük harf yoksayılsın mı?


98

Aşağıdaki basit örnek verildiğinde:

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

Görünüşe göre CaseInsensitiveComparer aslında büyük / küçük harfe duyarlı olmayan bir karşılaştırma yapmak için kullanılmıyor.

Başka bir deyişle, farklıList , listeyle aynı sayıda öğeyi içerir . Bunun yerine, örneğin "Üç" ve "üç" ün eşit kabul edilmesini beklerdim.

Eksik bir şey mi var yoksa bu Distinct operatörüyle ilgili bir sorun mu?

Yanıtlar:


236

StringComparer ihtiyacın olanı yapar:

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

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

(veya karşılaştırdığınız verilere bağlı olarak değişmez / sıra / vb.)


5

[En özlü yaklaşımı istiyorsanız Marc Gravells cevabına bakın]

Biraz araştırma ve Bradley Grainger'dan iyi geri bildirim aldıktan sonra aşağıdaki IEqualityComparer'ı uyguladım. Büyük / küçük harfe duyarlı olmayan Distinct () ifadesini destekler (yalnızca bunun bir örneğini Distinct operatörüne iletin):

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
}

6
Buna ihtiyacınız yok. Cevabımı görün.
Marc Gravell

2
Evet, cevabınız tam "Cevabınızı Gönderin" i tıkladığımda geldi.
Ash

Kesinlikle 20 saniyeden az bir süre içindeydiler, hatırlıyorum. Yine de, IEqualityComparer <T> gibi bir şeyi uygulamak, sadece nasıl çalıştığını anlamak için hala yararlı bir alıştırma ...
Marc Gravell

Tekrar teşekkürler, kimse şiddetle itiraz etmezse bu cevabın yayınlanmasına izin vereceğim.
Ash

Mevcut kültür en-US ise bu örnek tr-TR kültürü için başlatıldığında başarısız olur, çünkü GetHashCode, I (U + 0049) ve ı (U + 0131) için farklı değerler rapor ederken, Eşittir bunları eşit kabul eder.
Bradley Grainger

1

 ## 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 Olacak

   USA 
   INDIA
   UK

3
Lütfen açıklama yapmadan kod parçacıkları göndermekten kaçının. Cevabınızı düzenleyin ve ona bir gövde ekleyin. Teşekkürler.
Clijsters

0

İşte çok daha basit bir versiyon.

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();
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.