The for loop over an array
A for loop runs a block of code once for every element of a collection. In Scala the loop has three parts: a loop variable, the generator arrow <-, and the collection:
val languages = Array("Python", "Java", "Scala")
for (language <- languages) {
println("I love " + language)
}
Read the header as "for each language taken from languages". On each pass the variable language holds the next element, starting with the first. When the array has no more elements, the loop ends and the program continues with the line after the closing brace.
I love Python
I love Java
I love Scala
Which lines belong to the loop
When the body is in braces, the braces decide. Every statement written between { and } is part of the loop body and runs once per element. Anything after the closing brace is not part of the loop and runs once, after the loop is over.
With two statements in the body, both repeat together:
val languages = Array("Python", "Java", "Scala")
for (language <- languages) {
println("I love " + language)
println("I want to get better at it")
}
I love Python
I want to get better at it
I love Java
I want to get better at it
I love Scala
I want to get better at it
Move the second println after the closing brace and it is no longer repeated:
val languages = Array("Python", "Java", "Scala")
for (language <- languages) {
println("I love " + language)
}
println("I want to get better at them")
I love Python
I love Java
I love Scala
I want to get better at them
Execution flow
A program starts at its first line and runs one line at a time from top to bottom. That order is its execution flow. A loop does not break the rule: when the flow reaches the loop, it runs the body for each element, and only then goes on to the next line below it.
val fruits = Array("banana", "apple", "kiwi")
println("I'm hungry!")
for (fruit <- fruits) {
println("I'm gonna eat:")
println(fruit)
}
println("I love my life!")
I'm hungry!
I'm gonna eat:
banana
I'm gonna eat:
apple
I'm gonna eat:
kiwi
I love my life!
The first line prints once because it comes before the loop. The two lines in the body print three times, once per fruit. The last line prints once because it comes after.
The exercise
The editor starts with an array and two print statements. The program must print a heading, then each language on its own line, then a closing line:
Today we'll learn about:
Python
Java
JavaScript
Let's code!
The array in the editor holds "Python", "Java" and "JavaScript". Add a loop between the two prints:
- Write the header with the loop variable
language:for (language <- languages) {. - Put one statement in the body:
println(language)prints the current element on its own line. - Close the brace. The final
println("Let's code!")must stay after it, so that it runs only once.
The finished program:
val languages = Array("Python", "Java", "JavaScript")
println("Today we'll learn about:")
// Write the for loop below:
for (language <- languages) {
println(language)
}
println("Let's code!")
Gotchas
- Braces and indentation. A loop on one line, such as
for (x <- xs) println(x), repeats just that statement. Scala 3 also lets you drop the braces and use indentation instead, in which case the indented lines form the body. This lesson uses braces, which make the body explicit. - The loop variable belongs to the loop. It exists only inside the braces. Using
languagein a line after the loop gives aNot foundcompile error. - Don't move the closing message into the loop. It would print three times.
- Arrow direction. The generator is
<-, pointing from the collection to the variable.
Key takeaways
- A
forloop runs its body once per element, with the loop variable holding the current element. - The braces decide which statements repeat; everything after the closing brace runs once, after the loop.
- Execution flows from top to bottom, and a loop is one step in that flow.
