Start learning free

LESSON 225 OF 674 · LOOPS WITH STRINGS, ARRAYS & DICTIONARIES

Looping Over Dictionaries in C#

Lesson Read the full explanation

TL ; DR:

A foreach loop over a Dictionary visits every entry. Each entry has a Key and a Value.


Dictionary<string, int> stock = new Dictionary<string, int>();
stock["apples"] = 5;
stock["pears"] = 2;

foreach (var pair in stock) {
    Console.WriteLine(pair.Key + " " + pair.Value);
}

// apples 5
// pears 2   (no order is promised)


Full lesson:

A loop can visit every entry of a dictionary, one at a time. The loop body runs once per key.

Each entry is a KeyValuePair<string, int>. var lets C# work out that type for you.

Loop over stock.Keys to get only the keys. You can still read each value with its key.

foreach (string fruit in stock.Keys) {
    Console.WriteLine(fruit + " " + stock[fruit]);
}

The order: a Dictionary doesn't promise any order. Don't count on the order you added the keys in. A total or a count comes out the same in any order. Those are safe answers.

Watch out: don't add keys inside the loop. C# stops with an InvalidOperationException.


Your task

A game keeps each player's points in scores. The variables total and count start at 0.

Loop over scores. Add each entry's Value to total. Count the players with 10 points or more in count.

The code at the bottom prints both.

Expected output:

43
2
STEP 1 OF 3
    Ctrl + Enter to check

    C# · LOOPS WITH STRINGS, ARRAYS & DICTIONARIES

    Looping Over Dictionaries in C#, explained

    What a dictionary loop does

    A foreach loop over a Dictionary visits every entry once. The loop body runs one time per key. You can read the entry's key and its value inside the body.

    Dictionary<string, int> stock = new Dictionary<string, int>();
    stock["apples"] = 5;
    stock["pears"] = 2;
    
    foreach (var pair in stock) {
        Console.WriteLine(pair.Key + " " + pair.Value);
    }
    

    Output:

    apples 5
    pears 2
    

    Each entry is a KeyValuePair<string, int>, with a Key property and a Value property. Writing var lets C# work that type out, so you don't have to type it.

    Looping over the keys only

    If you only need the keys, loop over stock.Keys. You can still read each value by indexing the dictionary with its key:

    foreach (string fruit in stock.Keys) {
        Console.WriteLine(fruit + " " + stock[fruit]);
    }
    

    This prints the same two lines. stock.Values works the same way when you only need the values, for example to add them up.

    Values only, and unpacking each entry

    When the keys don't matter, loop over Values. For the scores in the exercise below, this adds up the points:

    int sum = 0;
    foreach (int points in scores.Values) {
        sum += points;
    }
    Console.WriteLine(sum);   // 43
    

    C# can also unpack an entry into two variables in the loop header, which reads well when you use both parts:

    foreach (var (name, points) in scores) {
        Console.WriteLine(name + ": " + points);
    }
    

    This prints Ana: 12, Ben: 7, Cleo: 15 and Dan: 9 on separate lines. Looping over an empty dictionary is fine: the body simply never runs, so a total stays at 0.

    Order, and a trap

    A Dictionary makes no promise about the order of its entries. In a small program that only adds entries, they often come out in the order you added them, but don't rely on it. Write loops whose answer doesn't depend on the order: a total, a count or a check are safe.

    Don't add keys to a dictionary while you loop over it. The loop stops with an InvalidOperationException:

    foreach (var pair in stock) {
        stock["kiwis"] = 1;   // throws: Collection was modified; enumeration operation may not execute.
    }
    

    Collect the changes first and apply them after the loop.

    The exercise

    The dictionary scores holds each player's points: Ana 12, Ben 7, Cleo 15 and Dan 9. The variables total and count start at 0. The task is to add every player's points to total, and to count the players with 10 points or more.

    1. Write a foreach loop over scores with var pair.
    2. Inside it, add pair.Value to total.
    3. Still inside, if pair.Value is 10 or more, add 1 to count.
    Dictionary<string, int> scores = new Dictionary<string, int>();
    scores["Ana"] = 12;
    scores["Ben"] = 7;
    scores["Cleo"] = 15;
    scores["Dan"] = 9;
    int total = 0;
    int count = 0;
    
    foreach (var pair in scores) {
        total += pair.Value;
        if (pair.Value >= 10) {
            count += 1;
        }
    }
    
    Console.WriteLine(total);
    Console.WriteLine(count);
    

    Output:

    43
    2
    

    12 + 7 + 15 + 9 is 43, and only Ana (12) and Cleo (15) reach 10. Both answers are the same whatever order the loop visits the players in.

    Common mistakes

    • Adding the pair instead of its value. total += pair doesn't compile, because pair is a key-value pair, not an int. Write total += pair.Value.
    • Lowercase property names. C# names are case sensitive: it is Key and Value, not key and value.
    • Using Length. A dictionary reports its number of entries as Count. If you only need the number of entries, you don't need a loop at all.
    • Counting in the wrong place. The check for 10 or more belongs inside the loop, next to the addition, so it runs once per player.

    Key takeaways

    • foreach (var pair in dict) gives each entry; use pair.Key and pair.Value.
    • dict.Keys and dict.Values loop over just one side.
    • Don't depend on the order of entries.
    • Don't add keys while looping over the dictionary.
    Keep going with C#500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free