Start learning free

LESSON 113 OF 414 · FOR LOOPS - LOOPING OVER ARRAYS

Looping Over Arrays in Scala: Fixing the Message Loop

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

    SCALA · FOR LOOPS - LOOPING OVER ARRAYS

    Buggy Code For Loops 2 in Scala, explained

    What the code is supposed to do

    The array languages holds "Python", "Java" and "JavaScript". The loop should print one sentence per language, with that language's name in it:

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

    The starter code compiles and runs, but it prints the same line three times:

    val languages = Array("Python", "Java", "JavaScript")
    
    for (language <- languages) {
        println("I think language is cool!")
    }
    
    I think language is cool!
    I think language is cool!
    I think language is cool!
    

    What goes wrong

    The loop itself is fine. It runs three times and the variable language holds a different value on each pass. The bug is in the message: everything inside double quotes is plain text. The characters l-a-n-g-u-a-g-e in the string are just letters, and the compiler does not look for a variable with that name. The string is the same on every pass, so the output is the same on every pass.

    The loop variable is created, but nothing ever reads it. To use its value, the message has to be built from the variable rather than typed as fixed text.

    Two ways to build the message

    Scala offers string interpolation: put an s directly in front of the opening quote, and then $language inside the string is replaced by the variable's value. For a plain variable name, that is all it takes.

    You can also join pieces with +:

    println("I think " + language + " is cool!")
    

    Both print the same text. Interpolation is the form the lesson uses, and the one most Scala code prefers because the sentence stays readable.

    How the loop runs

    It helps to follow the passes one at a time. On the first pass, language holds "Python", the body runs, and the message is built from that value. On the second pass the same variable holds "Java", and on the third "JavaScript". After the third element, the array has no more items, so the loop ends. The body is the same code every time; only the value of the loop variable changes, and that is why the message has to use the variable to differ.

    The starter output is a useful clue for this kind of bug. When a loop prints the same line on every pass, the body is probably not reading the loop variable at all. When a loop prints different but wrong values, the variable is being used and the problem is somewhere else.

    Fixing it step by step

    1. Find the part of the sentence that changes. Only the language name differs from pass to pass; the rest of the sentence is constant.
    2. Add the s prefix before the opening quote so that Scala interprets $ inside the string.
    3. Replace the word language in the sentence with $language, which refers to the loop variable.

    The fixed code in Scala

    val languages = Array("Python", "Java", "JavaScript")
    
    for (language <- languages) {
        println(s"I think $language is cool!")
    }
    
    /* Explanation:
    
    Notice that in the original code we didn't actually use the loop variable "language" inside the println() statement.
    And so on each iteration, the println() printed "I think language is cool!" no matter if language = "Python" or language = "Java" etc.
    The fix is to use the loop variable "language" with string interpolation to dynamically construct the message:
    
    for (language <- languages) {
        println(s"I think $language is cool!")
    }
    
    */
    

    It prints:

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

    Details worth knowing about interpolation:

    • The prefix is required. Without the s, "I think $language is cool!" is an ordinary string, and the output contains a literal $language.
    • Braces for expressions. $language takes a simple name. For a method call or any expression, use braces: s"${language.length} letters" prints 6 letters for Python. Note that $languages(0) would not index the array: it inserts the array itself and then the text (0). Write ${languages(0)} instead.
    • A literal dollar sign. Inside an s string, write $$ to print one $.

    Common mistakes

    • Quoting the variable. Writing the variable's name inside plain quotes prints the name, not the value.
    • Forgetting the s after adding $. The dollar sign then shows up in the output.
    • Missing spaces with +. "I think" + language + "is cool!" prints I thinkPythonis cool!. The spaces belong inside the quoted pieces.
    • Changing the array. The array is correct as it is; the bug is only in how the message is built.
    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free