C# Dictionary

A Dictionary<TKey, TValue> stores data as key-value pairs. Each key is unique, and you use it to look up its associated value — like looking up a word in a real dictionary to find its meaning.

The Key-Value Concept

┌──────────────────────────────────────────────────────────────┐
│                DICTIONARY — KEY-VALUE PAIRS                  │
├───────────────────────┬──────────────────────────────────────┤
│ Key                   │ Value                                │
├───────────────────────┼──────────────────────────────────────┤
│ "Name"                │ "Alice"                              │
│ "Age"                 │ 30                                   │
│ "Country"             │ "India"                              │
├───────────────────────┼──────────────────────────────────────┤
│ Keys must be unique   │ Values can repeat                    │
│ Like an index         │ Like a lookup result                 │
└───────────────────────┴──────────────────────────────────────┘

Real-world analogy: A phone book
  Name (key) → Phone Number (value)
  "Alice"    → "555-1234"
  "Bob"      → "555-5678"

Creating a Dictionary

using System;
using System.Collections.Generic;

// Empty dictionary: string keys, int values
Dictionary<string, int> ages = new Dictionary<string, int>();

// Dictionary with initial values:
Dictionary<string, string> capitals = new Dictionary<string, string>()
{
    { "France",  "Paris" },
    { "Germany", "Berlin" },
    { "Japan",   "Tokyo" }
};

Adding and Updating Items

Dictionary<string, int> scores = new Dictionary<string, int>();

// Add new entries:
scores.Add("Alice", 90);
scores.Add("Bob", 75);
scores.Add("Carol", 88);

// Update existing entry:
scores["Alice"] = 95;       // overwrite Alice's score

// Add or update using indexer (safe):
scores["Dave"] = 82;        // adds Dave if not present, updates if present

Dictionary Add Diagram

┌──────────────────────────────────────────────────────────────┐
│            DICTIONARY INTERNAL STRUCTURE                     │
├────────────────┬─────────────────────────────────────────────┤
│ Hash of Key    │ Bucket → Key-Value Pair                     │
├────────────────┼─────────────────────────────────────────────┤
│ hash("Alice")  │ "Alice" → 90                                │
│ hash("Bob")    │ "Bob"   → 75                                │
│ hash("Carol")  │ "Carol" → 88                                │
└────────────────┴─────────────────────────────────────────────┘

Lookup is O(1) — instant access by key (no scanning)

Accessing Values

Dictionary<string, string> capitals = new Dictionary<string, string>()
{
    { "France", "Paris" },
    { "Japan",  "Tokyo" }
};

// Direct access (throws exception if key missing):
Console.WriteLine(capitals["France"]);  // Paris

// Safe access with TryGetValue:
if (capitals.TryGetValue("Japan", out string capital))
{
    Console.WriteLine(capital);         // Tokyo
}

// Check if key exists before accessing:
if (capitals.ContainsKey("Germany"))
{
    Console.WriteLine(capitals["Germany"]);
}
else
{
    Console.WriteLine("Germany not found.");
}

Removing Items

scores.Remove("Bob");       // removes the "Bob" entry
Console.WriteLine(scores.ContainsKey("Bob"));  // False

Iterating Through a Dictionary

Dictionary<string, int> prices = new Dictionary<string, int>()
{
    { "Apple",  50 },
    { "Mango",  80 },
    { "Banana", 30 }
};

// Loop through all key-value pairs:
foreach (KeyValuePair<string, int> item in prices)
{
    Console.WriteLine(item.Key + " costs " + item.Value);
}
// Output:
// Apple costs 50
// Mango costs 80
// Banana costs 30

// Loop through keys only:
foreach (string key in prices.Keys)
{
    Console.WriteLine(key);
}

// Loop through values only:
foreach (int price in prices.Values)
{
    Console.WriteLine(price);
}

Common Properties and Methods

Dictionary<string, int> d = new Dictionary<string, int>()
{
    { "A", 1 }, { "B", 2 }, { "C", 3 }
};

Console.WriteLine(d.Count);              // 3
Console.WriteLine(d.ContainsKey("B"));  // True
Console.WriteLine(d.ContainsValue(3));  // True

d.Remove("A");
Console.WriteLine(d.Count);             // 2

d.Clear();
Console.WriteLine(d.Count);             // 0

Real Example: Word Frequency Counter

using System;
using System.Collections.Generic;

string[] words = { "cat", "dog", "cat", "bird", "dog", "cat" };

Dictionary<string, int> frequency = new Dictionary<string, int>();

foreach (string word in words)
{
    if (frequency.ContainsKey(word))
        frequency[word]++;     // increment count
    else
        frequency[word] = 1;   // first occurrence
}

foreach (KeyValuePair<string, int> entry in frequency)
{
    Console.WriteLine(entry.Key + ": " + entry.Value + " times");
}
// Output:
// cat: 3 times
// dog: 2 times
// bird: 1 times

Word Counter Flow Diagram

┌────────────────────────────────────────────────────────────┐
│  Input: ["cat","dog","cat","bird","dog","cat"]             │
├────────────────────────────────────────────────────────────┤
│                                                            │
│  Process "cat"  → {"cat": 1}                               │
│  Process "dog"  → {"cat": 1, "dog": 1}                     │
│  Process "cat"  → {"cat": 2, "dog": 1}                     │
│  Process "bird" → {"cat": 2, "dog": 1, "bird": 1}          │
│  Process "dog"  → {"cat": 2, "dog": 2, "bird": 1}          │
│  Process "cat"  → {"cat": 3, "dog": 2, "bird": 1}          │
│                                                            │
└────────────────────────────────────────────────────────────┘

Nested Dictionary

A dictionary can hold another dictionary as its value. This models hierarchical data like country → cities.

Dictionary<string, List<string>> countryCities = new Dictionary<string, List<string>>()
{
    { "India",  new List<string>() { "Delhi", "Mumbai", "Chennai" } },
    { "USA",    new List<string>() { "New York", "Los Angeles" } }
};

foreach (string city in countryCities["India"])
{
    Console.WriteLine(city);
}
// Delhi, Mumbai, Chennai

Quick Reference

┌────────────────────────────┬────────────────────────────────┐
│ Method/Property            │ What It Does                   │
├────────────────────────────┼────────────────────────────────┤
│ Add(key, value)            │ Add new key-value pair         │
│ Remove(key)                │ Remove entry by key            │
│ ContainsKey(key)           │ Check if key exists            │
│ ContainsValue(val)         │ Check if value exists          │
│ TryGetValue(key, out val)  │ Safe lookup — no exception     │
│ Clear()                    │ Remove all entries             │
│ Count                      │ Number of entries              │
│ Keys                       │ Collection of all keys         │
│ Values                     │ Collection of all values       │
└────────────────────────────┴────────────────────────────────┘

Dictionary is the go-to collection when you need fast lookup by a unique key. It powers features like caching, user session data, configuration settings, and data aggregation. Knowing it well makes many real-world coding tasks significantly easier.

Leave a Comment

Your email address will not be published. Required fields are marked *