Start learning free

LESSON 113 OF 415 · FOR LOOPS - LOOPING OVER ARRAYS

Looping Over Arrays in Swift: Fixing the Buggy Code

Practice Read the full explanation

Inside the code editor we've tried to write a for loop that prints a tailored message about every language in the languages array.

So when we ran the code, we expected it to print:

I think Python is cool!
I think Java is cool!
I think JavaScript is cool!

but it seems like we made some mistakes because when we run our code, it produces this output:

I think language is cool!
I think language is cool!
I think language is cool!

Assignment:

Your task is to fix our loop such that it will print the desired output.

STEP 1 OF 1
    Ctrl + Enter to check

    SWIFT · FOR LOOPS - LOOPING OVER ARRAYS

    Buggy Code For Loops 2 in Swift, explained

    What the code is supposed to do

    The program has an array named languages holding three strings and a for loop that should print one sentence per language. The expected output is:

    I think Python is cool!
    I think Java is cool!
    I think JavaScript is cool!
    

    The code you start with produces three lines too, but every line is the same:

    let languages = ["Python", "Java", "JavaScript"]
    
    for language in languages {
        print("I think language is cool!")
    }
    

    It prints I think language is cool! three times. Your job is to make the sentence change with each pass of the loop.

    What goes wrong

    The loop itself is correct. for language in languages runs its body once per element, and on each pass the constant language holds the current element: first "Python", then "Java", then "JavaScript".

    The bug is inside the body. The text between the quotes is a string literal, and Swift prints a literal exactly as written. The word language in "I think language is cool!" is just seven letters of text, not a reference to the loop variable. The variable is created on every pass and then never used.

    The compiler notices this and warns that the immutable value language was never used and suggests replacing it with _. A warning about an unused loop variable is often the first clue that a loop body ignores its element.

    Fixing it step by step

    1. Find the part of the message that must change. The words I think and is cool! stay the same on every line. Only the language name differs.
    2. Cut that part out of the literal. The string now has a gap between I think and is cool!.
    3. Fill the gap with string interpolation. Writing \(language) inside the quotes tells Swift to put the value of language at that spot.
    4. Keep everything else. The array, the loop header and the print call are already right.

    The fixed code in Swift

    let languages = ["Python", "Java", "JavaScript"]
    
    for language in languages {
        print("I think \(language) is cool!")
    }
    

    A few Swift details are worth knowing here:

    • Interpolation is a backslash and parentheses. Inside a string literal, \( ... ) evaluates the expression between the parentheses and inserts the result as text. It can hold more than a name: "\(language.count) letters" inserts the length of the name.
    • Plain quotes never interpolate. Without the backslash, parentheses inside a string are ordinary characters. Interpolation needs the exact form \( ... ).
    • The loop variable is a constant. language is declared by the loop as a let, so the body can read it but cannot assign to it.
    • Unused loop variables. When a loop only needs to repeat and does not need the element, write for _ in languages. The underscore means "I don't need a name for this".
    • The scope is the loop body. language exists only between the braces, so the name is not available after the closing brace.

    Common mistakes

    • Putting the variable inside the quotes without interpolation. This is the bug in the lesson. "I think language is cool!" prints the word, not the value.
    • Using the wrong quotes or no backslash. "I think (language) is cool!" prints the parentheses and the word literally, because without the backslash they are ordinary characters.
    • Printing outside the loop. Moving the print call after the closing brace would not compile, because language does not exist there.
    • Changing the array. The output depends on the strings in languages. Keep them in this order: Python, Java, JavaScript.
    • Mismatched text. The lesson's tests compare the output exactly, so the capital I, the spaces and the exclamation mark all count.

    Checking your fix

    Run the program in the editor above. A correct fix prints the three sentences, each with a different language, and the unused-variable warning disappears because the loop variable is now used.

    Keep going with SwiftAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free