TOC

This article has been localized into Czech by the community.

Sbírky:

Slovníky

Slovníky v C# implementují rozhraní IDictionary. Existuje několik typů slovníků, ale nejčastěji používaným je generický slovník, často označovaný jako Dictionary<TKey, TValue> - obsahuje klíč specifického typu a odpovídající hodnotu specifického typu. To je v podstatě to, co odlišuje slovník od seznamu - položky seznamu jsou v určitém pořadí a lze k nim přistupovat pomocí číselného indexu, zatímco položky ve slovníku jsou uloženy s jedinečným klíčem, který lze pak použít k opětovnému načtení položky.

Prozkoumáme podrobněji, o co u slovníků jde, ale nejprve se podívejme na jednoduchý příklad:

Dictionary<string, int> users = new Dictionary<string, int>();  
users.Add("John Doe", 42);  
users.Add("Jane Doe", 38);  
users.Add("Joe Doe", 12);  
users.Add("Jenna Doe", 12);

Console.WriteLine("John Doe is " + users["John Doe"] + " years old");

Seznamte se s rodinou Doeových, kteří jsou opět testovacími daty pro příklad v tomto tutoriálu. Táta, máma a dvojčata Joe a Jenna. Všimněte si, jak definuji slovník tak, aby používal řetězec jako klíč (v tomto případě jméno) a celé číslo pro hodnotu (v tomto případě věk). Skvělé na tom je, že to umožňuje přistupovat k položce ze slovníku pomocí klíče (jména) místo číselného indexu. To můžete vidět v akci v poslední řádce příkladu - mezi sadou hranatých závorek jednoduše určíme klíč, abychom přistoupili k hodnotě (věku).

Zde jsou dvě důležité věci, které je třeba vědět: Zaprvé, klíč musí být jedinečný. V tomto případě, kdy používáme řetězec jako klíč, to znamená, že nemůžete přidat dva uživatele se zcela stejným jménem. To dává docela dobrý smysl, protože když můžete použít klíč k odkazování na jednu položku, klíč může ukazovat pouze na jednu hodnotu. Na druhou stranu to dělá tento příklad trochu příliš jednoduchým, protože zřejmě nemůžete mít sbírku uživatelů, kde by neexistovala duplicitní jména, ale prozatím to tak nechte.

Druhá věc, na kterou si musíte pamatovat při přístupu k hodnotám ze slovníku, je, že klíč musí v kolekci existovat, když se pokoušíte přistoupit k jeho hodnotě. Jinými slovy, můj příklad byl bezpečný pouze proto, že jsem měl plnou kontrolu nad tím, co seznam obsahoval - ve většině situací byste měli vždy nejprve zkontrolovat, zda klíč existuje, než se ho pokusíte použít - jako toto:

string key = "John Doe";
if(users.ContainsKey(key))
    Console.WriteLine("John Doe is " + users[key] + " years old");

Pokud se pokusíte přidat klíč, který již existuje, nebo pokud se pokusíte přistoupit k hodnotě s klíčem, který neexistuje, .NET vyvolá výjimku. To může znít samozřejmě, ale obě situace jsou ve skutečnosti velmi často nacházeny v protokolech výjimek po celém světě.

Práce s položkami

Přístup k jednotlivé položce může být velmi užitečný, ale co když chcete projít celou kolekci a například něco hledat? V takovém případě byste měli nejprve vědět, že položky v seznamu zřejmě nejsou jen jednoduché objekty - místo toho slovník uchovává položky typu <TKey, TValue>. T značí typy, které jste použili pro deklaraci seznamu - v tomto případě řetězec a celé číslo. Projít kolekci pomocí smyčky foreach by tedy vypadalo nějak takto:

Dictionary<string, int> users = new Dictionary<string, int>()
{
    { "John Doe", 42 },
    { "Jane Doe", 38 },
    { "Joe Doe", 12 },
    { "Jenna Doe", 12 }
};
foreach (KeyValuePair<string, int> user in users)
{
    Console.WriteLine(user.Key + " is " + user.Value + " years old");
}

První věc, které si můžete všimnout, je, že jsem využil příležitosti změnit způsob, jakým inicializujeme slovník - místo ručního přidávání každé položky po vytvoření instance slovníku, používáme syntaxi inicializátoru kolekce, jak bylo popsáno v předchozím článku.

S tímto za námi máme nyní stejný slovník jako předtím - pojďme si jej projít. Jak vidíte, používám smyčku foreach a deklaroval jsem typ položky, kterou očekávám, jako KeyValuePair<string, int> - přesně stejné dva typy použité pro deklaraci slovníku. Nyní můžeme přistupovat jak ke klíči, tak k hodnotě (jméno a věk) pro každou položku a používáme to k vygenerování jednoduchého řetězce informací o osobě do konzoly.

Pořadí položek

Výše uvedený příklad nás přivádí k velmi důležitému bodu: Na rozdíl od seznamu (List), kde je základní pořadí položek určeno číselnými indexy, pořadí položek ve slovníku je nedeterministické - jednoduše se nemůžete spolehnout na to, že položky budou v určitém pořadí, ani když každou položku přidáte ručně. Samozřejmě, když spustíte výše uvedený příklad, pravděpodobně zjistíte, že položky jsou ve stejném pořadí, jak jsme je přidali, ale to není zaručené, a jakmile máte slovník s více položkami a začnete přidávat a odebírat položky, pořadí se pravděpodobně změní.

Třída Dictionary nemá metodu Sort(), protože nakonec, i když ji seřadíte, pořadí se může změnit, jakmile s ní začnete znovu pracovat. Místo toho můžete použít metody OrderBy() a OrderByDescending() z LINQ (více o tom v další kapitole), abyste získali seřazenou kopii slovníku. To vám také umožní seřadit buď podle klíče, nebo podle hodnoty, což by mohlo být užitečné v našem příkladu, abyste získali uživatele v pořadí podle jejich věku:

Dictionary<string, int> users = new Dictionary<string, int>()
{
    { "John Doe", 42 },
    { "Jane Doe", 38 },
    { "Joe Doe", 12 },
    { "Jenna Doe", 12 }
};
foreach (KeyValuePair<string, int> user in users.OrderBy(user => user.Value))
{
    Console.WriteLine(user.Key + " is " + user.Value + " years old");
}

Pokud spustíte příklad, uvidíte, že i když je slovník deklarován s položkami v jednom pořadí, můžeme je snadno získat v jiném pořadí, jak se nám hodí. Jen si pamatujte, že jste zodpovědní za zajištění toho, abyste položky získali v pořadí, v takovém jaké chcete, protože .NET framework je ukládá přesně tak, jak se mu to hodí.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!