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.