.NET Tip #39: Case-insensitive Dictionary a HashSet

Tomáš Jecha, MVP, MCSD       11.02.2012             10135 zobrazení

Tento článek je krátkou ukázkou použití slovníku a hashsetu, kde je hlavní hodnotou řetězec, u kterého chceme ignorovat velikost písmen. Takové chování může být výhodou v nespočtu případů.

Pokud si vytvoříme běžnou instanci slovníku nebo hashsetu, kde klíčem je string, lze přidávat různé kombinace velkých a malých písmen. Následující příklad vloží do slovníku a hashsetu 3 hodnoty. Ačkoliv jsou řetězce stejné, mají různou velikost písmen a proto se vloží záznamy vícekrát.

// DICTIONARY

var dict = new Dictionary<string, int>();
dict["first"] = 1;
dict["First"] = 2;
dict["FIRST"] = 3;

// ve slovníku jsou 3 záznamy ("first"; 1), ("First"; 2) a ("FIRST"; 3)

// HASHSET

var hashSet = new HashSet<string>();
hashSet.Add("first");
hashSet.Add("First");
hashSet.Add("FIRST");

// v hashsetu jsou 3 záznamy ("first", "First", "FIRST")

Pro použití case-insensitive chování použijeme explicitní comparer (doslovně - porovnávač). Ten je realizován jako samostatná třída. A její srovnávací funkce popisuje několik rozhraní:

  • IComparer – porovnává dva objekty a výsledkem je jedna z možností: větší, menší, stejný
  • IComparer<typ> – stejné jako IComparer, jen silně typový
  • IEqualityComparer – porovnává, zda jsou objekty stejné nebo ne a navíc dokáže vypočítat hash instance (hash se používá k identifikaci objektu v Dictionary i HashSet)
  • IEqualityComparer<string> – stejné jako IEqualityComparer, jen silně typový

Konkrétně použijeme jeden z comparerů typu StringComparer – slouží k porovnávání řetězců a implementuje všechny uvedené rozhraní. Já konkrétně většinou využívám variantu StringComparer.OrdinalIgnoreCase (velikost písmen nerozhoduje, diakritika ano).

Comparer lze předat v konstruktoru Dictionary i HashSetu:

// DICTIONARY

var dict = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
dict["first"] = 1;
dict["First"] = 2;
dict["FIRST"] = 3;

// ve slovníku je pouze 1 záznam ("first"; 3)

// HASHSET

var hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
hashSet.Add("first");
hashSet.Add("First");
hashSet.Add("FIRST");

// v hashsetu je pouze 1 záznam ("first")

Ta samá ukázka pro Visual Basic .NET:

' DICTIONARY

Dim dict As New Dictionary(Of String, Integer)(StringComparer.OrdinalIgnoreCase)
dict("first") = 1
dict("First") = 2
dict("FIRST") = 3

' ve slovníku je pouze 1 záznam ("first"; 3)

' HASHSET
Dim hashSet As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
hashSet.Add("first")
hashSet.Add("First")
hashSet.Add("FIRST")

' v hashsetu je pouze 1 záznam ("first")

 

hodnocení článku

2 bodů / 2 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback