Scala: For loop version 2.0

Rahul
Lethal Brains
Published in
2 min readOct 21, 2015

--

Most programmers would have introduced to the iteration world through the for loop. It has been simple and straight forward though these years. But lately our requirements out of this iterative control structure bas been increasing(functional paradigm, cartesian product, etc). Scala’s for loop has evolved to a next level to quench our thirst.

Basic

The basic functionality of a for loop is to iterate. Here is how you iterate from 1 to 10 using Scala’s for loop

scala> for(i <- 1 to 3)
| println(i)
1
2
3

The left-arrow <- operator is called a generator as it generates individual values for the range or the collection on the right hand side. For loop can also be used to iterate over collections

scala> for(i <- List("world", "galaxy", "universe"))
| println("hello "+ i + "!!")
hello world!!
hello galaxy!!
hello universe!!

Multiple generators

Scala lets you have multiple generators in your for loop. When you have multiple generators, the loop iterators for both the generators.

scala> val starks = List("Robb", "Sansa", "Arya")
starks: List[String] = List(Robb, Sansa, Arya)
scala> val lannisters = List("Cersei", "Jaime","Tywin")
lannisters: List[String] = List(Cersei, Jaime, Tywin)
scala> for(stark <- starks; lannister <- lannisters)
| println(stark + " Stark hates " + lannister + " Lannister")
Robb Stark hates Cersei Lannister
Robb Stark hates Jaime Lannister
Robb Stark hates Tywin Lannister
Sansa Stark hates Cersei Lannister
Sansa Stark hates Jaime Lannister
Sansa Stark hates Tywin Lannister
Arya Stark hates Cersei Lannister
Arya Stark hates Jaime Lannister
Arya Stark hates Tywin Lannister

Think of the previous example as a double for loop. The output is the cartesian product of both the collections.

Guards (Filtering)

Scala also lets you to have guards for your iteration i.e. you can filter your collection prior to the iteration

scala> for{stark <- starks; lannister <- lannisters;
| if stark.startsWith("R")
| }
| println(stark + " Stark hates " + lannister + " Lannister")
Robb Stark hates Cersei Lannister
Robb Stark hates Jaime Lannister
Robb Stark hates Tywin Lannister

As seen above both {} and () can be used interchangeably but the convention is to use {} for multi lines and () for single line.

Yield

By using yield keyword, you can return the values from a for loop. This was the functional paradigm, that I was talking about earlier. This helps us to separate the computation which makes our code much more reusable.

val multipledByThree = for(i <- List(1,2,3)) yield i * 3
multipledByThree: List[Int] = List(3, 6, 9)

If you want to have a side effect along with your yield, you can do the following

scala> val multipledByThree = for(i <- List(1,2,3)) yield {
| println(i)
| i * 3
| }
1
2
3
multipledByThree: List[Int] = List(3, 6, 9)
scala> println(multipledByThree)
List(3, 6, 9)

Variables declared inside a for loop are of type val, hence reassignment will throw an error

scala> for {i <- 1 to 5}{
| i= i + 1
| print(i)
| }
<console>:13: error: reassignment to val
i= i + 1
^

--

--

AWS certified Solution Architect | Node.js - Machine learning Engineer | Amateur photographer