92 votes

LINQ Opérateur distinct, ignorer la casse?

Étant donné l'exemple simple suivant:

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

Il apparaît que CaseInsensitiveComparer n'est pas réellement utilisé pour effectuer une comparaison insensible à la casse.

En d'autres termes, distinctList contient le même nombre d'éléments que la liste . Au lieu de cela, je m'attendrais par exemple à ce que "Trois" et "Trois" soient considérés comme égaux.

Est-ce que je manque quelque chose ou est-ce un problème avec l'opérateur Distinct?

218voto

Marc Gravell Points 482669

StringComparer fait ce dont vous avez besoin:

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

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

(ou invariant / ordinal / etc en fonction des données que vous comparez)

5voto

Ash Points 31541

[Voir la réponse de Marc Gravells si vous voulez l'approche la plus concise]

Après quelques investigations et de bons retours de Bradley Grainger, j'ai implémenté le IEqualityComparer suivant. Il importe une instruction Distinct () insensible à la casse (il suffit de passer une instance de cela à l'opérateur 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
}
 

1voto

Ash Points 31541

Je remarque dans "LINQ Pocket Reference" (O'Reilly) que:

1.12.4. Distinct Distinct renvoie la séquence d'entrée débarrassée des doublons. Seul le comparateur d'égalité par défaut peut être utilisé pour la comparaison d'égalité.

Je me demande pourquoi alors Distinct () fournit une surcharge acceptant un IEqualityComparer?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X