2010-04-19 9 views
59

Comment utiliser la méthode HashSet<string>.Contains() en cas de mode insensible?Comment utiliser HashSet <string> Méthode .Contains() en cas - mode insensible?

+4

Un sidenode: quand un 'normal' '' HashSet (sensible à la casse) est créé, il est impossible de créer une méthode 'contains' qui est efficace. Ceci parce que les hachages des éléments sont créés quand ils sont ajoutés au 'HashSet'. Et en interne, la méthode 'contains' vérifie les hachages pour être efficace. Il n'est pas possible de convertir (efficacement) une forme de hachage existante 'sensible à la casse' en 'insensible à la casse'. – Julian

Répondre

100

Vous pouvez créer le HashSet avec un comparateur personnalisé:

HashSet<string> hs = new HashSet<string>(StringComparer.OrdinalIgnoreCase); 

hs.Add("Hello"); 

Console.WriteLine(hs.Contains("HeLLo")); 
+13

+1 Parce que vous utilisez 'Ordinal' au lieu de' InvariantCulture'. Les directives .NET nous conseillent de ne pas utiliser 'InvariantCulture' dans la plupart des cas (voir: http://msdn.microsoft.com/en-us/library/ms973919.aspx). – Steven

+1

CurrentCultureIgnoreCase est généralement le meilleur choix. –

+3

@HansPassant pourquoi? – guiomie

9

Vous devez créer avec le droit IEqualityComparer:

HashSet<string> hashset = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); 
5

Vous devez utiliser le constructor qui vous permet de spécifier le IEqualityComparer vous voulez utiliser.

HashSet<String> hashSet = new HashSet<String>(StringComparer.InvariantCultureIgnoreCase); 

L'objet StringComparer fournit un certain comparateur souvent utilisé comme propriétés statiques.

4

Ce n'est pas nécessaire ici, comme d'autres réponses l'ont démontré, mais dans les autres cas où vous n'utilisez pas de chaîne, vous pouvez choisir d'implémenter un IEqualityComparer<T> et ensuite utiliser une surcharge .Contains. Voici un exemple utilisant une chaîne de caractères (encore une fois, d'autres réponses ont montré qu'il existe déjà un comparateur de chaînes que vous pouvez utiliser pour répondre à vos besoins). Beaucoup de méthodes entourant IEnumerable<T> ont des surcharges qui acceptent de tels comparateurs, il est donc bon d'apprendre à les implémenter.

class CustomStringComparer : IEqualityComparer<string> 
{ 
    public bool Equals(string x, string y) 
    { 
     return x.Equals(y, StringComparison.InvariantCultureIgnoreCase); 
    } 

    public int GetHashCode(string obj) 
    { 
     return obj.GetHashCode(); 
    } 
} 

Et puis l'utiliser

bool contains = hash.Contains("foo", new CustomStringComparer());