Start learning free

LESSON 222 OF 671 · LOOPS WITH STRINGS, ARRAYS & DICTIONARIES

Looping Over Dictionaries in JavaScript

Lesson Read the full explanation

TL ; DR:

A for...in loop visits every key of an object. Read each value with its key in square brackets.


const stock = {"apples": 5, "pears": 2};

for (const fruit in stock) {
    console.log(fruit, stock[fruit]);
}

// apples 5
// pears 2


Full lesson:

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

for...in gives the keys of an object. Inside the loop, stock[fruit] reads the value of the current key.

You can also get each key with its value in one go. Loop over Object.entries(stock), where each entry is a [key, value] pair.

for (const [fruit, amount] of Object.entries(stock)) {
    console.log(fruit, amount);
}

The order: an object keeps word keys, like these names, in the order they were added. Keys that look like whole numbers come first. Many other languages keep no order. A total or a count comes out the same in any order. Those are safe answers.

Watch out: in and of are different. for...of straight on an object fails with "stock is not iterable".


Your task

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

Loop over scores. Add every player's points, scores[name], 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

    JAVASCRIPT · LOOPS WITH STRINGS, ARRAYS & DICTIONARIES

    Looping Over Dictionaries in JavaScript, explained

    What it is

    In JavaScript, a plain object works as a dictionary: it maps keys to values. A loop can visit every entry, one at a time, and the body runs once per key. This is how you add up all the values, count the entries that meet a rule, or print everything.

    Two ways to loop

    for...in gives the keys of an object. Inside the loop, square brackets read the value of the current key:

    const stock = {"apples": 5, "pears": 2};
    
    for (const fruit in stock) {
        console.log(fruit, stock[fruit]);
    }
    
    apples 5
    pears 2
    

    To get each key together with its value, loop over Object.entries(stock). Each entry is a [key, value] pair, and the loop can unpack it right in the header:

    for (const [fruit, amount] of Object.entries(stock)) {
        console.log(fruit, amount);
    }
    

    It prints the same two lines. Object.keys(stock) gives just the keys as an array, [ 'apples', 'pears' ], and Object.values(stock) gives just the values, [ 5, 2 ].

    The order

    An object keeps text keys in the order they were added, so apples comes before pears above. Many other languages make no such promise, so write code that gives the same answer in any order. A total or a count does. Be careful with keys that look like whole numbers: JavaScript visits those first, in ascending order, before the other keys. For {b: 1, a: 2, 10: "x", 2: "y"} the loop visits 2, 10, b, a.

    Traps

    • for...of straight on an object fails. An object is not iterable, so for (const x of stock) throws the error "stock is not iterable". Use for...in, or for...of over Object.entries(stock).
    • in gives keys, not values. With for (const v in scores), adding v to a number glues text together: a total that starts at 0 turns into 0AnaBenCleoDan.
    • Dot access names a literal key. Inside the loop, scores.name looks for a key called name, which doesn't exist, so it is undefined and a total built from it ends as NaN. Use scores[name] to read the key held in the variable.

    The exercise, step by step

    A game keeps each player's points in scores. 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 for...in loop over scores with a const named name for the key, and close its brace right away.
    2. Inside it, add scores[name] to total.
    3. Below that, if scores[name] is 10 or more, add 1 to count.
    const scores = {"Ana": 12, "Ben": 7, "Cleo": 15, "Dan": 9};
    let total = 0;
    let count = 0;
    for (const name in scores) {
        total += scores[name];
        if (scores[name] >= 10) {
            count += 1;
        }
    }
    console.log(total);
    console.log(count);
    

    The output is:

    43
    2
    

    The total is 12 + 7 + 15 + 9 = 43, and Ana and Cleo are the two players with 10 or more.

    The same exercise with entries

    The loop with Object.entries gives the same result, and it reads the value only once per player. The variable points holds the value directly, so the loop body never writes scores[name]:

    for (const [name, points] of Object.entries(scores)) {
        total += points;
        if (points >= 10) {
            count += 1;
        }
    }
    

    It also prints 43 and 2. Either form is fine; the lesson's tests only look at the printed output.

    Key takeaways

    • for (const key in obj) visits each key; read the value with obj[key].
    • Object.entries(obj) gives [key, value] pairs for for...of.
    • A plain object is not iterable, so for...of on it directly is an error.
    • Totals and counts don't depend on the order of the keys.
    Keep going with JavaScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free