Learn How To Use For Comprehension

By Nadim Bahadoor | Last updated: July 25, 2017 at 13:36 pm

Overview

In this tutorial, we will go over the for comprehension construct in Scala. If you are coming from another mainstream language such as Java or .NET, a for loop should be fairly self explanatory in that you are writing a piece of code to iterate over some data points.

 

But, the Scala for comprehension can do much more! As an example and similar to the previous tutorial on using IF And Else Expressions, the for construct in Scala can return a value!

Steps

1. A simple for loop from 1 to 5 inclusive
Let's show how to do a simple for loop by iterating from 1 to 5 and print the immutable variable numberOfDonuts during each iteration.


println("Step 1: A simple for loop from 1 to 5 inclusive")
for(numberOfDonuts <- 1 to 5){
  println(s"Number of donuts to buy = $numberOfDonuts")
}

You should see the following output when you run your Scala application in IntelliJ:


Number of donuts to buy = 1
Number of donuts to buy = 2
Number of donuts to buy = 3
Number of donuts to buy = 4
Number of donuts to buy = 5

NOTE:

  • We used the keyword to which meant that iteration number 5 was included.

2. A simple for loop from 1 to 5, where 5 is NOT inclusive

What if we wanted to iterate through numbers 1 to 4? In other words, the last iteration for number 5 will not be included. If you have used Java or .NET for loop to iterate through arrays or other collections, I'm pretty sure that at some point you must have encountered bugs in your code because you had used a <= instead of < or vice versa in your loop.

Scala's language fluency with the use of keyword until makes it clear that your for loop will NOT include the last iteration.


println("\nStep 2: A simple for loop from 1 to 5, where 5 is NOT inclusive")
for(numberOfDonuts <- 1 until 5){
  println(s"Number of donuts to buy = $numberOfDonuts")
}

You should see the following output when you run your Scala application in IntelliJ:


Number of donuts to buy = 1
Number of donuts to buy = 2
Number of donuts to buy = 3
Number of donuts to buy = 4

NOTE:

  • We used of keyword until which meant that the iteration number 5 was NOT included.

3. Filter values using if conditions in for loop

Now that you are familiar with the for loop syntax from Step 1 and 2, let us show that in Scala you can also use if clause to add filtering support as you iterate through your items.

As an example, let's store a List of ingredients for baking donuts into an immutable variable called donutIngredients. We then loop through each ingredient in the list and filter out all items except for the "sugar" item.


println("\nStep 3: Filter values using if conditions in for loop")
val donutIngredients = List("flour", "sugar", "egg yolks", "syrup", "flavouring")
for(ingredient <- donutIngredients if ingredient == "sugar"){
  println(s"Found sweetening ingredient = $ingredient")
}

You should see the following output when you run your Scala application in IntelliJ:


Found sweetening ingredient = sugar

NOTE:

  • This is the first time we are showing how to declare and use a List. If you are coming from Java or .NET, you may be surprised not to find the new keyword used when declaring the List object. This is made possible in Scala using companion objects which we will see in upcoming tutorials.
  • We used the if expression within the for loop itself!
  • There are however better ways at filtering out items from collections which we will see in upcoming tutorials.

4. Filter values using if conditions in for loop and return the result back using the yield keyword

Let's expand the example in Step 3 and filter for either "sugar" or "syrup" ingredients in our donutsIngredients list. Instead of using the (), we are using the {} in our for comprehension to make our expressions more explicit.

In addition, to return the result of the for comprehension and store it in the sweeteningIngredients variable, we will make use of the yield keyword.


println("\nStep 4: Filter values using if conditions in for loop and return the result back using the yield keyword")
val sweeteningIngredients = for {
  ingredient <- donutIngredients
  if (ingredient == "sugar" || ingredient == "syrup")
} yield ingredient
println(s"Sweetening ingredients = $sweeteningIngredients")

You should see the following output when you run your Scala application in IntelliJ:


Sweetening ingredients = List(sugar, syrup)

5. Using for comprehension to loop through 2-Dimensional array

It is very common in other programming languages to work with 2-Dimensional arrays. Let's create a 2-Dimensional array consisting of 4 elements of our donuts Ingredients.

To do this, we will use Scala Array class and call the ofDim() function, pass in the type of String in square brackets [String] and then specify our 2 by 2 array in the function parameter. We then fill in each element of our 2-Dimensional array as follows:


val twoDimensionalArray = Array.ofDim[String](2,2)
twoDimensionalArray(0)(0) = "flour"
twoDimensionalArray(0)(1) = "sugar"
twoDimensionalArray(1)(0) = "egg"
twoDimensionalArray(1)(1) = "syrup"

To iterate through your 2-Dimensional array, you can use the for comprehension and first declare an x variable to loop from 0 until 2, followed by a second iteration again from 0 until 2 which you will store in variable y. After the closing } of our for loop, you can call println() to print each element of our 2-Dimensional array.


for { x <- 0 until 2
       y <- 0 until 2
} println(s"Donut ingredient at index ${(x,y)} = ${twoDimensionalArray(x)(y)}")

You should see the following output when you run your Scala application in IntelliJ:


Step 5: Using for comprehension to loop through 2-Dimensional array
Donut ingredient at index (0,0) = flour
Donut ingredient at index (0,1) = sugar
Donut ingredient at index (1,0) = egg
Donut ingredient at index (1,1) = syrup

NOTE:

This concludes our tutorial on Learn How To Use For Comprehension and I hope you've found it useful!

 

Stay in touch via Facebook and Twitter for upcoming tutorials!

 

Don't forget to like and share this page :)

Summary

In this tutorial, we went over the following:

  • How to use a for comprehension to loop and iterate from 1 to 5 inclusive
  • How to use a for comprehension to loop and iterate from 1 until 5, where the fifth iteration is not included
  • How to filter values using if conditions in a for loop
  • How to create and use for comprehension for looping over 2-Dimensional arrays.

Tip

  • As you get more familiar with functional style of programming, Scala's for comprehension will quickly become your new best friend :)
  • Moreover, as we get to tutorials on say Futures, you will see even more hidden powers of the for comprehension!

Source Code

The source code is available on the allaboutscala GitHub repository.

 

What's Next

In the next tutorial, I will explain in more detail Scala's Range construct. As an example, our for loop in Step 1 contained a simple range which was numberOfDonuts <-1 to 5

 

Stay tuned!

Nadim Bahadoor on FacebookNadim Bahadoor on GithubNadim Bahadoor on LinkedinNadim Bahadoor on Twitter
Nadim Bahadoor
Senior Software Developer | Elsevier
Founder of allaboutscala.com. I have over 10 years of experience in building large scale real-time trading systems in the financial industry. Passionate about Distributed Systems, Scala, Big Data and Functional Programming. Stay in touch for upcoming tutorials!
Other allaboutscala.com tutorials you may like:

Share this article on