0Pricing
C# Academy · Lekcja

Wyszukiwanie w Dictionary

Szybki dostęp do wartości po kluczu.

Wyszukiwanie w Dictionary to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.

Pary klucz-wartość

Dictionary<TKey, TValue> mapuje unikalne klucze na wartości. Można myśleć o nim jak o tabeli wyszukiwania: podaje się klucz i szybko otrzymuje odpowiadającą mu wartość.

Jest oparty na tablicy mieszającej, dlatego wyszukiwanie wartości po kluczu zajmuje średnio O(1), czyli znacznie mniej niż przeszukiwanie listy.

using System.Collections.Generic;

var ages = new Dictionary<string, int>();
ages["Ann"] = 30;
ages["Bob"] = 25;

Inicjalizacja Dictionary

Słownik można wstępnie wypełnić za pomocą inicjalizatora kolekcji. Każdy wpis łączy klucz z jego wartością.

Klucze muszą być unikalne. Podanie tego samego klucza dwukrotnie w inicjalizatorze spowoduje w czasie wykonywania wyjątek ArgumentException.

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var caps = new Dictionary<string, string> {
            ["FR"] = "Paris",
            ["JP"] = "Tokyo"
        };
        Console.WriteLine(caps["JP"]);
    }
}

Odczyt według klucza

Do odczytu należy użyć indeksatora: dict[key]. Średnia złożoność tej operacji to O(1).

Należy jednak zachować ostrożność: jeśli klucza nie ma, indeksator zgłasza wyjątek KeyNotFoundException. Odczyt nieistniejącego klucza jest jednym z najczęstszych błędów podczas pracy ze słownikiem.

var ages = new Dictionary<string, int> { ["Ann"] = 30 };
int a = ages["Ann"];      // 30
// int b = ages["Zoe"];   // throws KeyNotFoundException

Bezpieczne wyszukiwanie za pomocą TryGetValue

TryGetValue pozwala uniknąć wyjątków. Zwraca true i ustawia zmienną out, gdy klucz istnieje, albo false w przeciwnym razie.

To idiomatyczny sposób wyszukiwania wartości, co do której istnienia nie mają Państwo pewności, bez dodatkowych alokacji.

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var ages = new Dictionary<string, int> { ["Ann"] = 30 };
        if (ages.TryGetValue("Ann", out int v))
            Console.WriteLine(v);
    }
}

ContainsKey i wartości domyślne

ContainsKey sprawdza obecność klucza bez odczytywania wartości, w czasie O(1). Należy użyć go przed odczytem przez indeksator, gdy potrzebna jest tylko odpowiedź tak lub nie.

Wywołanie zarówno ContainsKey, jak i indeksatora powoduje dwukrotne obliczenie skrótu klucza. TryGetValue robi to raz, dlatego zazwyczaj działa szybciej.

var ages = new Dictionary<string, int> { ["Ann"] = 30 };
if (ages.ContainsKey("Ann"))
    System.Console.WriteLine(ages["Ann"]);

Dodawanie a przypisywanie

Indeksator dict[key] = value wstawia nową parę albo zastępuje istniejącą. Add(key, value) tylko wstawia element i zgłasza wyjątek, jeśli klucz już istnieje.

Należy użyć Add, gdy zduplikowany klucz powinien być błędem, a indeksatora — gdy zastępowanie wartości jest dozwolone.

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var d = new Dictionary<string, int>();
        d["x"] = 1;
        d["x"] = 2;     // overwrite, fine
        Console.WriteLine(d["x"]);
    }
}

Usuwanie elementów

Remove(key) usuwa parę i zwraca true, jeśli klucz był obecny. Średnia złożoność tej operacji to O(1).

Jedno z przeciążeń zwraca usuniętą wartość za pośrednictwem parametru out. Jest to przydatne, gdy chcą Państwo usunąć wartość i od razu jej użyć.

var d = new Dictionary<string, int> { ["a"] = 1, ["b"] = 2 };
bool removed = d.Remove("a");   // true
bool again = d.Remove("a");     // false

Iterowanie po parach

Pętla zwraca elementy typu KeyValuePair<TKey, TValue>. Można je rozłożyć na klucz i wartość, aby uzyskać czytelny kod.

Kolejność podczas wyliczania nie jest gwarantowana — nigdy nie należy polegać na kolejności wstawiania elementów. Za pomocą Keys lub Values można iterować tylko po jednej stronie par.

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var d = new Dictionary<string, int> { ["a"] = 1, ["b"] = 2 };
        foreach (var (key, val) in d)
            Console.WriteLine($"{key}={val}");
    }
}

Zliczanie za pomocą słownika

Klasycznym zastosowaniem jest zliczanie wystąpień. Dla każdego elementu należy zwiększyć licznik, ustawiając go najpierw na zero, jeśli element pojawia się po raz pierwszy.

Ten wzorzec działa w czasie O(n) dla n elementów, ponieważ każde wyszukiwanie i uaktualnienie ma złożoność O(1). Dla porównania, każdorazowe przeszukiwanie listy miałoby złożoność O(n kwadrat).

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var counts = new Dictionary<char, int>();
        foreach (char c in "banana")
            counts[c] = counts.GetValueOrDefault(c) + 1;
        Console.WriteLine(counts['a']);
    }
}

Równość kluczy ma znaczenie

Wyszukiwanie korzysta z metod GetHashCode i Equals typu klucza. Typy wbudowane oraz string działają od razu bez dodatkowej konfiguracji.

W przypadku kluczy będących niestandardowymi klasami należy przesłonić obie metody lub użyć typu record. W przeciwnym razie dwa klucze wyglądające na równe otrzymają różne skróty i wyszukiwanie się nie powiedzie.

var byName = new Dictionary<string, int>(
    System.StringComparer.OrdinalIgnoreCase);
byName["Hi"] = 1;
bool found = byName.ContainsKey("HI"); // true

Wybór typu wartości

Wartości mogą być dowolnego typu, także typu listy. Dictionary<string, List<int>> grupuje wiele wartości pod jednym kluczem.

Podczas wstawiania do takiej struktury należy utworzyć wewnętrzną listę przy pierwszym użyciu, a następnie dodać do niej element. W ten sposób powstaje mapa grupująca wiele wartości.

var groups = new Dictionary<string, List<int>>();
void Add(string k, int v) {
    if (!groups.TryGetValue(k, out var list))
        groups[k] = list = new List<int>();
    list.Add(v);
}

Szybkie sprawdzenie

Należy wybrać najbezpieczniejszy sposób odczytu klucza, którego może nie być.

Podsumowanie

Dictionary<K,V> zapewnia średnią złożoność O(1) wyszukiwania, wstawiania i usuwania według klucza, korzystając z tablicy haszującej.

Należy preferować TryGetValue zamiast indeksatora zgłaszającego wyjątek, pilnować unikatowości kluczy oraz zapewnić prawidłową implementację równości i funkcji skrótu dla niestandardowych typów kluczy. Kolejność iteracji jest nieokreślona.

Często zadawane pytania

Czy lekcja „Wyszukiwanie w Dictionary” jest bezpłatna?

Tak — pełny tekst „Wyszukiwanie w Dictionary” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Wyszukiwanie w Dictionary”?

Szybki dostęp do wartości po kluczu. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C# Academy?

Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Wyszukiwanie w Dictionary”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?

Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Lista w praktyce
  2. Wyszukiwanie w Dictionary
  3. HashSet i unikatowość
  4. Wybór kolekcji
← Powrót do C# Academy