E blokk · Tömbök, listák, Dictionary · 5. tananyag
A tömb és a lista sorszám szerint ad vissza elemet.
Sokszor viszont egy név érdekel: mennyi alma van
raktáron? Mi Anna telefonszáma? Két párhuzamos tömbbel ez megoldható, de
minden lekérdezéshez végig kell keresni a neveket. A
Dictionary a kulcsot
közvetlenül az értékhez rendeli: keszlet["alma"]
— és kész.
Dictionary<TKey, TValue>-t,
és tudod, mi a kulcs és mi az érték.Add, indexelés), és tudod, mi a különbség
a kettő között.ContainsKey,
TryGetValue).foreach a kulcs-érték párokon).Dictionary kell.Dictionary<string, int> keszlet = new Dictionary<string, int>(); keszlet["alma"] = 40; keszlet["körte"] = 12; keszlet["szilva"] = 0; Console.WriteLine(keszlet["alma"]); // 40
Dictionary kulcs-érték
párokat tárol. Az első típusparaméter a kulcs
típusa (string — a termék neve), a második
az értéké (int — a
darabszám).Dictionary is generikus
(E4), és szintén a
System.Collections.Generic névtérben
van.Kezdőértékekkel is létrehozható:
Dictionary<string, string> szotar = new Dictionary<string, string> { ["kutya"] = "dog", ["macska"] = "cat", ["ló"] = "horse" };
Két módon kerülhet új pár a Dictionary-be,
és a különbség fontos:
keszlet.Add("banán", 25); // új pár — ha a kulcs már létezik: KIVÉTEL keszlet["banán"] = 30; // ha létezik: felülírja; ha nem: létrehozza
| Művelet | Ha a kulcs még nincs benne | Ha a kulcs már benne van |
|---|---|---|
Add(kulcs, ertek) | felveszi a párt | ArgumentException — a program leáll |
d[kulcs] = ertek | felveszi a párt | felülírja az értéket |
Az Add tehát akkor jó, ha a kulcs ismétlődése
hiba lenne (pl. két diák ugyanazzal az azonosítóval); az
indexelés, ha a felülírás a kívánt viselkedés. Létező érték módosítása
indexeléssel: keszlet["alma"] += 10;
Ha a kulcs nincs a Dictionary-ben,
az olvasás kivételt okoz:
Console.WriteLine(keszlet["dinnye"]); // KeyNotFoundException: The given key 'dinnye' was not present in the dictionary.
Két eszköz védi ki:
if (keszlet.ContainsKey("dinnye")) { Console.WriteLine(keszlet["dinnye"]); } else { Konzol.Hiba("Nincs ilyen termék."); }
if (keszlet.TryGetValue("körte", out int darab)) { Console.WriteLine($"Körte: {darab} db"); } else { Konzol.Hiba("Nincs ilyen termék."); }
A TryGetValue a
D3-as
TryParse-minta újabb példája: a visszatérési érték a siker
(bool), az out
paraméter az eredmény.
bool torolve = keszlet.Remove("szilva"); // true, ha volt ilyen kulcs Console.WriteLine(keszlet.Count); // a párok száma
A bejárás kulcs-érték párokon megy végig:
foreach (KeyValuePair<string, int> par in keszlet) { Console.WriteLine($"{par.Key,-10}{par.Value,5} db"); }
KeyValuePair-t
ad: a Key a kulcs, a
Value az érték.var
(B1):
foreach (var par in keszlet). A fordító
tudja, hogy KeyValuePair<string, int>.keszlet.Keys,
keszlet.Values.A Dictionary nem garantálja, hogy a
bejárás a felvétel sorrendjében történik. Ha rendezett kiírás kell,
arra később látunk eszközt.
A Dictionary egyik leggyakoribb felhasználása
a gyakoriság számlálása — hány szavazatot kapott egy
jelölt, hányszor fordul elő egy szó:
Dictionary<string, int> szavazatok = new Dictionary<string, int>(); string szavazat; do { Console.Write("Szavazat (üres sor: vége): "); szavazat = Console.ReadLine(); if (szavazat != "") { if (szavazatok.ContainsKey(szavazat)) { szavazatok[szavazat]++; // már van ilyen: növeljük } else { szavazatok[szavazat] = 1; // első szavazat erre a jelöltre } } } while (szavazat != ""); foreach (var par in szavazatok) { Console.WriteLine($"{par.Key}: {par.Value} szavazat"); }
A lényeg a belső if: ha a kulcs már létezik,
növeljük; ha még nem, felvesszük 1-es értékkel. Ez az
E2-es megszámlálás
tétele, csak most sok számláló egyszerre — kulcsonként egy.
| Kérdés | Gyűjtemény |
|---|---|
| fix darabszámú elem, sorszám szerint | tömb (T[]) |
| változó darabszámú elem, sorrendben | lista (List<T>) |
| érték név / azonosító szerint keresve | Dictionary<TKey, TValue> |
Sorszám szerint, fix mérettel — sorszám szerint, változó mérettel — vagy név szerint?
| Tünet | Mi történt? | Mit tegyél? |
|---|---|---|
ArgumentException: An item with the same key has already been added | Add létező kulccsal | felülíráshoz indexelés; vagy előbb ContainsKey |
KeyNotFoundException | nem létező kulcsot olvastál | ContainsKey vagy TryGetValue előtte |
| a „Körte” nem található, pedig „körte” van benne | a kulcs kis-nagybetű érzékeny | egységesíts (pl. mindig kisbetűvel tárolj — I blokk: ToLower) |
| a kiírás sorrendje más, mint a felvételé | a Dictionary nem garantál sorrendet | ne építs a sorrendre |
CS1061 a par.Kulcs-ra | a pár tulajdonságai angol nevűek | par.Key és par.Value |
| a számláló kivétellel indul | az első előfordulásnál d[kulcs]++ — a kulcs még nem létezik | előbb ContainsKey, az első esetben = 1 |
Raktar, .NET 10 +
Konzol.cs.Dictionary<string, int>
készletet néhány kezdő termékkel.TryGetValue),
[K] Kilépés.Raktar: Dictionary menuvel.A meglévő termék beérkezése növeli a darabszámot, az új felveszi; a nem létező termék kiadása és keresése nem okoz kivételt; a készletnél többet nem lehet kiadni.
⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás
Hozz létre egy magyar–angol szótárt öt szóval, kérj be egy magyar szót, és írd ki a fordítását — ha nincs a szótárban, jelezd.
Tárold öt ország fővárosát
(Dictionary<string, string>), és írd
ki az összes párt „Ország: főváros” alakban.
Kérj be egy mondatot, bontsd szavakra
(mondat.Split(' ') — string-tömböt ad
vissza), és írd ki, melyik szó hányszor fordul elő.
Egy osztály diákjainak pontszámait tárold név szerint. Írd ki a legtöbb pontot elért diák nevét és pontszámát (maximumkiválasztás a párokon).
Kérj be egy szöveget, és írd ki, melyik betű hányszor szerepel benne
(Dictionary<char, int>) — a
szóközöket hagyd ki.
Minden kérdésnél egy válasz helyes. A végén pontszámot kapsz.
| Fogalom | Jelentés |
|---|---|
Dictionary<TKey, TValue> | kulcs-érték párok gyűjteménye; az érték a kulccsal érhető el |
| kulcs | egyedi azonosító, amely alapján az értéket keressük |
| érték | a kulcshoz rendelt adat |
Add | új pár felvétele — létező kulcsnál kivétel |
ContainsKey | szerepel-e a kulcs |
TryGetValue | ellenőrzés és kiolvasás egy lépésben (TryParse-minta) |
KeyValuePair | egy kulcs-érték pár; tulajdonságai Key és Value |
| gyakoriságszámlálás | kulcsonkénti számlálás Dictionary-vel |
Dictionary
kulcs-érték párokat tárol; a kulcs egyedi, az érték a kulccsal
érhető el: d["alma"].Add: új pár, létező
kulcsnál kivétel; indexelés: létrehoz vagy
felülír.ContainsKey vagy
TryGetValue.KeyValuePair-eken
megy (Key,
Value); a sorrendre ne építs.Dictionary: sorszám fix
mérettel, sorszám változó mérettel, név szerint. A következő oldal
ezeket gyakoroltatja együtt.