Start learning free

LESSON 238 OF 675 · SETS

Removing From a Set and Looping Over It in TypeScript

Lesson Read the full explanation

TL ; DR:

delete(x) takes x out of a set. A for...of loop visits every value once.


let colors = new Set<string>(["red", "blue", "green"]);

colors.delete("blue");

colors.delete("pink");          // not in it, nothing happens

for (let color of colors) {
    console.log(color);         // red, then green
}


Full lesson:

s.delete(x) removes x from the set s. It returns true if x was there. If it wasn't, nothing happens and it returns false.

for (let x of s) visits each value of the set once.

A TypeScript set loops in the order the values were added. Most languages don't promise any order for a set. So a set is best for work where the order doesn't matter. A total, a count and a check are fine.

A set has no indexes. A for loop with i and s[i] doesn't work on it. Use for...of.


Your task

In a word game, the set found holds the words a player found. The words "qqq" and "zzz" aren't allowed. Remove both from found.

The player never found "zzz", so removing it changes nothing.

Then add up the points. A word scores one point per letter. Loop over found and add each word's length to score.

The code already prints how many words are left, and the points.

Expected output:

4 words
14 points
STEP 1 OF 3
    Ctrl + Enter to check

    TYPESCRIPT · SETS

    Removing From Sets in TypeScript, explained

    Removing a value

    s.delete(x) takes x out of the set s. It returns true if the value was there and false if it was not. Deleting a value that is missing is not an error: nothing happens.

    let words: string[] = ["cat", "tree", "sun", "qqq", "moon"];
    let found: Set<string> = new Set(words);
    
    console.log(found.delete("qqq"));
    console.log(found.delete("zzz"));
    console.log(found.size + " words");
    

    This prints:

    true
    false
    4 words
    

    The first call found "qqq" and removed it. The second found nothing and left the set alone. Because a missing value is harmless, you never need an if (s.has(x)) check before calling delete.

    Looping over a set

    for (let x of s) visits each value of the set once. A set has no indexes, so a counting loop with s[i] does not work. Use for...of.

    A TypeScript set loops in the order the values were added. Many other languages promise no order at all, so a set is best for work where the order does not matter, such as a total, a count or a check. Those give the same answer in any order.

    Deleting while looping

    Deleting the value you are currently visiting is allowed. For new Set([1, 2, 3, 4]), a loop that deletes every even value leaves 1 3. It is still simpler to read when the loop only reads the set, and the changes happen in separate statements.

    Counting while looping

    The loop body can do more than add. This one counts the words with more than three letters. The pattern is the same as for a total: start a variable at 0 before the loop, change it inside, and read it after.

    let found: Set<string> = new Set(["cat", "tree", "sun", "moon"]);
    let longWords: number = 0;
    for (let word of found) {
        if (word.length > 3) {
            longWords += 1;
        }
    }
    console.log(longWords);
    

    It prints 2, for "tree" and "moon".

    Mistakes to avoid

    • Using for...in on a set. for...in gives the keys of an object. A set has no such keys, so the loop body never runs and the program carries on silently. for...of is the loop for the values of a set.
    • Indexing. Reading found[0] or looping with i < found.size and found[i] gives undefined every time, because a set has no positions.
    • Checking before deleting. An if around delete is extra code. The call already does nothing for a missing value.
    • Removing everything. found.clear() empties the whole set at once; after it, found.size is 0.

    The exercise

    In a word game, the set found holds the words a player found. The words "qqq" and "zzz" are not allowed, so both have to go. The player never found "zzz", so removing it changes nothing. Then each word scores one point per letter, and score has to hold the total.

    1. Call found.delete("qqq") and found.delete("zzz"), one per line.
    2. Write a for...of loop over found with let word.
    3. Inside it, add word.length to score.
    let words: string[] = ["cat", "tree", "sun", "qqq", "moon"];
    let found: Set<string> = new Set(words);
    
    found.delete("qqq");
    found.delete("zzz");
    console.log(found.size + " words");
    
    let score: number = 0;
    for (let word of found) {
        score += word.length;
    }
    console.log(score + " points");
    

    The output is:

    4 words
    14 points
    

    The four words left are cat, tree, sun and moon, and 3 + 4 + 3 + 4 = 14.

    Key takeaways

    • delete(x) removes a value and returns whether it was there; a missing value is not an error.
    • for...of visits every value of a set once, in the order they were added.
    • Sets have no indexes, so index-based loops do not work on them.
    Keep going with TypeScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free