C# Academy · Lektion

Uppslag i dictionaries

Snabb åtkomst med nyckel och värde.

Lektion 2 av 413 steg

Uppslag i dictionaries är en gratis lektion i C# Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för C# Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i C# Academy innehåller totalt 4 lektioner.

Nyckel-värde-par

Dictionary<TKey, TValue> mappar unika nycklar till värden. Tänk på den som en uppslagstabell: ange en nyckel och få snabbt tillbaka värdet.

Den bygger på en hashtabell, så det tar i genomsnitt O(1) att hitta ett värde via dess nyckel, vilket är mycket snabbare än att söka igenom en lista.

using System.Collections.Generic;

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

Initiera en Dictionary

En dictionary kan initieras med en samlingsinitierare. Varje post kopplar en nyckel till dess värde.

Nycklar måste vara unika. Om samma nyckel anges två gånger i en initierare kastas ArgumentException vid körning.

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"]);
    }
}

Läsa med nyckel

Använd indexeraren för att läsa: dict[key]. Det tar i genomsnitt O(1).

Men var försiktig: om nyckeln saknas kastar indexeraren KeyNotFoundException. Att läsa en nyckel som saknas är ett av de vanligaste felen med dictionary.

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

Säker uppslagning med TryGetValue

TryGetValue undviker undantag. Den returnerar true och tilldelar en out-variabel när nyckeln finns, och annars false.

Det här är det idiomatiska sättet att slå upp ett värde som du är osäker på, utan allokeringar.

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 och standardvärden

ContainsKey kontrollerar om en nyckel finns utan att läsa värdet, på O(1). Använd den före en läsning med indexeraren när du bara behöver ett ja eller nej.

Om du anropar både ContainsKey och indexeraren hashar du nyckeln två gånger. TryGetValue gör det en gång och är därför vanligtvis snabbare.

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

Lägga till jämfört med tilldelning

Indexeraren dict[key] = value lägger in ett nytt par eller skriver över ett befintligt. Add(key, value) lägger bara in nya par och kastar ett undantag om nyckeln redan finns.

Använd Add när en dubblettnyckel ska vara ett fel, och indexeraren när det är okej att skriva över ett befintligt värde.

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"]);
    }
}

Ta bort poster

Remove(key) tar bort ett par och returnerar true om nyckeln fanns, i genomsnitt på O(1).

Det finns även en överlagring som returnerar det borttagna värdet via en out-parameter. Den är praktisk när du vill ta bort och använda värdet i ett enda steg.

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

Iterera över par

En loop ger objekt av typen KeyValuePair<TKey, TValue>. Dekomponera dem till en nyckel och ett värde för renare kod.

Uppräkningsordningen garanteras inte. Förlita dig aldrig på ordningen som posterna lades in i. Använd Keys eller Values för att iterera över bara den ena sidan.

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}");
    }
}

Räkna med en Dictionary

Ett klassiskt användningsområde är att räkna förekomster. För varje objekt ökar du dess antal och börjar från noll om det är nytt.

Mönstret körs på O(n) för n objekt eftersom varje uppslagning och uppdatering tar O(1), jämfört med O(n i kvadrat) om du genomsökte en lista varje gång.

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']);
    }
}

Nyckeljämförelse spelar roll

Uppslagningar bygger på GetHashCode och Equals för nyckeltypen. Inbyggda typer och string fungerar direkt.

För nycklar av anpassade klasstyper ska du åsidosätta båda metoderna eller använda en record. Annars hashashar två nycklar som ser likadana ut olika, och uppslagningarna misslyckas.

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

Välja en värdetyp

Värden kan vara vad som helst, även listor. En Dictionary<string, List<int>> grupperar många värden under en nyckel.

När du lägger in värden i en sådan struktur skapar du den inre listan första gången den används och lägger sedan till värdet i den. På så sätt bygger du en grupperad map med flera värden.

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);
}

Snabbkontroll

Välj det säkraste sättet att läsa en nyckel som eventuellt saknas.

Sammanfattning

Dictionary<K,V> ger i genomsnitt O(1) för uppslagning, insättning och borttagning med nyckel, med en hashtabell som underliggande struktur.

Föredra TryGetValue framför indexeraren som kastar undantag, håll nycklarna unika och se till att anpassade nyckeltyper implementerar korrekt jämförelse och hashing. Iterationsordningen är odefinierad.

Gratis att börja

Lär dig C# med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
93
Lektioner
346

Vanliga frågor

Är lektionen ”Uppslag i dictionaries” gratis?

Ja – hela texten till ”Uppslag i dictionaries” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i C# Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i C# Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Uppslag i dictionaries”?

Snabb åtkomst med nyckel och värde. Ni övar på C# Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig C# Academy?

Du behöver inga förkunskaper. Utbildningen i C# Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.

Hur lång tid tar lektionen ”Uppslag i dictionaries”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här C# Academy-lektionen?

Ja. Varje C# Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Listor i praktiken
  2. Uppslag i dictionaries
  3. HashSet och unikhet
  4. Välj rätt samling
← Tillbaka till C# Academy