.NET Tip #14: Generické kolekce (2/6) - Dictionary

Tomáš Jecha, MVP, MCSD       13.10.2008       C#, VB.NET, .NET Tips       14807 zobrazení

V minulém příspěvku jsem psal o generické kolekci List, která dokáže uchovávat položky datového typu, jenž si zvolíme generickým parametrem. Dictionary (neboli slovník) je jí velmi podobný. Liší se jen v tom, že v seznamu List se prvky identifikují podle indexu, který se může měnit v důsledku smazání, či vložení prvku s nižším indexem - vždy se totiž dodržovala posloupnost indexů 0 až počet mínus jedna. Dictionary oproti tomu nepracuje s indexem, ale ukládá prvky pod unikátním klíčem datového typu, který si volíme dalším generickým parametrem.

Vložení nového prvku pak vyžaduje přidání 2 hodnot - nejdříve klíče a potom samotné hodnoty. Také funkce Contains (zjišťující, zda prvek existuje se rozdělila na 2 - ContainsKey a ContainsValue = zjištující, zda existuje ve slovníku daný klíč a zda existuje daná hodnota). Mazání prvku se také provádí pomocí hodnoty klíče.

Krátký příklad použití ve VB.NET (první se při deklaraci uvádí typ klíče a jako druhý typ hodnoty - v našem příklad klíč je číslo zaměstnance a hodnota jména):

' vytvoření slovníku s klíčem typu INT a hodnotou typu STRING 
Dim jmena As New Dictionary(Of Integer, String)()

' přidání hodnot do kolekce (klíč je interéní číslo zaměstnance, hodnota pak jméno 
jmena.Add(18, "Karel Novák")
jmena.Add(420, "Petr Gulis")
jmena.Add(135, "Martina Bláhová")

' získání hodnoty pro klíč 18 
Console.WriteLine("Zaměstnance číslo 18: {0}", jmena(18))

' získání hodnoty pro klíč 135 
Console.WriteLine("Zaměstnance číslo 135: {0}", jmena(135))

' zjištění, zda existuje položka s klíčem 555 
If jmena.ContainsKey(555) = False Then
    Console.WriteLine("Zaměstnanec s číslem 555 neexistuje!")
Else
    Console.WriteLine("Zaměstnanec s číslem 555 je ve slovníku!")
End If

A v C#:

// vytvoření slovníku s klíčem typu INT a hodnotou typu STRING
Dictionary<int, string> jmena = new Dictionary<int, string>();

// přidání hodnot do kolekce (klíč je interéní číslo zaměstnance, hodnota pak jméno
jmena.Add(18, "Karel Novák");
jmena.Add(420, "Petr Gulis");
jmena.Add(135, "Martina Bláhová");

// získání hodnoty pro klíč 18
Console.WriteLine("Zaměstnance číslo 18: {0}", jmena[18]);

// získání hodnoty pro klíč 135
Console.WriteLine("Zaměstnance číslo 135: {0}", jmena[135]);

// zjištění, zda existuje položka s klíčem 555
if (jmena.ContainsKey(555) == false)
    Console.WriteLine("Zaměstnanec s číslem 555 neexistuje!");
else
    Console.WriteLine("Zaměstnanec s číslem 555 je ve slovníku!");

Na závěr chci ještě dodat způsob procházení slovníku cyklusem foreach. Máme 3 možnosti:

  1. Procházet jen hodnoty (bez klíčů):
    For Each hodnota As String In jmena.Values
        Console.WriteLine("Hodnota: {0}", hodnota)
    Next
  2. Procházet jen klíče:
    For Each klic As String In jmena.Keys
        Console.WriteLine("Klíč: {0}", klic)
    Next
  3. Procházet hodnoty i klíče pomocí datového typu KeyValuePair(Of TypKlíče, TypHodnoty) - ten má pak vlastnosti Key a Value:
    For Each polozka As KeyValuePair(Of Integer, String) In jmena
        Console.WriteLine("Pro klíč {0} odpovídá hodnota: {1}", polozka.Key, polozka.Value)
    Next

V této sérii jsem psal i o následujících třídách:

  • List
  • Dictionary
  • SortedDictionary a SortedList
  • Queue
  • Stack
  • HashSet
  •  

    hodnocení článku

    0       Hodnotit mohou jen registrované uživatelé.

     

    Nový příspěvek

     

    afrt

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Linq;

    using System.Text;

    using System.Threading.Tasks;

    using System.Windows.Forms;

    namespace _191015_Vlček

    {

    public partial class Form1 : Form

    {

    public Form1()

    {

    InitializeComponent();

    Mesta.NaplnDictionary(cbVyberMesto);

    }

    private void CbVyberMesto_SelectedIndexChanged(object sender, EventArgs e)

    {

    rtbVýpis.Text = Mesta.ZmenaIndexu(sender as ComboBox);

    }

    private void ButPridej_Click(object sender, EventArgs e)

    {

    rtbVýpis.Text = Mesta.PridaniMesta(tbPridejKlic.Text, tbPridejHodnota.Text, cbVyberMesto);

    }

    private void ButVymaz_Click(object sender, EventArgs e)

    {

    rtbVýpis.Text = Mesta.OdebraniMesta(cbVyberMesto);

    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)

    {

    Mesta.Uloz();

    }

    private void Form1_Load(object sender, EventArgs e)

    {

    }

    }

    }

    class

    namespace _191015_Vlček

    {

    class Mesta

    {

    static Dictionary<string, int> mestaAObyvatele = new Dictionary<string, int>();

    public static void NaplnDictionary(ComboBox cb)

    {

    if (File.Exists("t.txt"))

    {

    foreach (var item in File.ReadAllLines("t.txt"))

    {

    if(!mestaAObyvatele.ContainsKey(item.Split('*')[0])) mestaAObyvatele.Add(item.Split('*')[0], Convert.ToInt32(item.Split('*')[1]));

    }

    NaplnCB(cb);

    }

    else MessageBox.Show("Soubor neexistuje!", "Není soubor!", MessageBoxButtons.OK, MessageBoxIcon.Error);

    }

    public static string ZmenaIndexu(ComboBox cb)

    {

    return $@"{cb.SelectedItem}

    Počet obyvatel: {mestaAObyvatele[cb.SelectedItem.ToString()]}";

    }

    public static string PridaniMesta(string mesto, string pocetObyvatel, ComboBox cb)

    {

    try

    {

    if (mesto == "" || pocetObyvatel == "") return $"Prázdné nejde!";

    else if (mestaAObyvatele.ContainsKey(mesto)) return $"{mesto} už tam je!";

    else if (Convert.ToInt32(pocetObyvatel) <= 0) return $"Počet obyvatel musí být kladný!";

    else { mestaAObyvatele.Add(mesto, Convert.ToInt32(pocetObyvatel)); NaplnCB(cb); return $"Zadáno: {mesto} ({pocetObyvatel})"; }

    }

    catch (Exception er)

    {

    return er.Message;

    }

    }

    public static string OdebraniMesta(ComboBox cb)

    {

    if (cb.SelectedIndex >= 0) { string v = "Smazano: " + cb.SelectedItem.ToString() + " " + mestaAObyvatele[cb.SelectedItem.ToString()]; mestaAObyvatele.Remove(cb.SelectedItem.ToString()); cb.Items.RemoveAt(cb.SelectedIndex); return v; }

    else return "Není vybraná žádná položka!";

    }

    public static void Uloz()

    {

    string zapis = "";

    foreach (var item in mestaAObyvatele)

    {

    zapis += $"{item.Key}*{item.Value}\n";

    }

    File.WriteAllText("t.txt", zapis);

    }

    static void NaplnCB(ComboBox cb)

    {

    cb.Items.Clear();

    foreach (var item in mestaAObyvatele)

    {

    cb.Items.Add(item.Key);

    }

    }

    }

    }

    nahlásit spamnahlásit spam 0 odpovědětodpovědět
                           
    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