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 KeyNotFoundExceptionBezpieczne 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"); // falseIterowanie 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"); // trueWybó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
- Lista w praktyce
- Wyszukiwanie w Dictionary
- HashSet i unikatowość
- Wybór kolekcji