Loops
While
The while loop in Scala, as in many other programming languages, is a control flow statement that allows code to be executed repeatedly based on a given Boolean condition. The loop will continue to execute as long as the condition evaluates to true. It's a fundamental construct that's useful in scenarios where the number of iterations is not known before the loop starts.
while condition do
// Code block to be executed
Here, condition is a Boolean expression. If condition evaluates to true, the code block inside the while loop is executed. After each execution, condition is evaluated again, and if it's still true, the loop continues. This repeats until condition becomes false.
Example of while Loop
Let's look at a simple example where we use a while loop to iterate until a variable x becomes less than or equal to zero:
var x = 10
while x > 0 do
println(x)
x -= 1 // Decrement x by 1
In this example, we start with x equal to 10, and in each iteration of the loop, we decrement x by 1 and print the current value of x. The loop terminates when x is no longer greater than 0.
Considerations When Using while Loops
- Mutability:
whileloops often rely on mutable state (like thexvariable in the examples) to control the loop's execution. This can be at odds with Scala's emphasis on immutability and functional programming principles. - Functional Alternatives: In many cases, especially when working with collections, functional alternatives such as
foreach,for,map,filter, andfoldcan achieve the same results as awhileloop but in a more concise and expressive way. These constructs also encourage immutability and side-effect-free programming.
Example of Replacing while with Functional Constructs
Consider a scenario where we want to sum all numbers from 1 to n. Instead of using a while loop with mutable state, we could use a functional and immutable approach:
val n = 10
val sum = (1 to n).sum
println(sum)
This code snippet uses a range (1 to n) and the sum method to calculate the total sum in a concise, readable, and immutable manner.
For
for item <- collection do
// Do something with item
Examples
Iterating Over a Range
for i <- 1 to 5 do
println(i)
This will print numbers 1 through 5. Scala ranges are inclusive by default when you use to. If you want an exclusive range, you can use until:
for i <- 1 until 5 do
println(i)
This prints numbers 1 through 4.
Iterating Over a Collection
val fruits = List("apple", "banana", "cherry")
for fruit <- fruits do
println(fruit)
This iterates over each element in the fruits list and prints it.
For-Comprehensions
Scala's for loop can also be used to create new collections from existing ones, a feature known as for-comprehensions. When used in this way, you enclose the iteration logic in parentheses and use the yield keyword to produce values that form a new collection.
Example: Squaring Numbers
val numbers = List(1, 2, 3, 4, 5)
val squaredNumbers = for n <- numbers yield n * n
println(squaredNumbers) // List(1, 4, 9, 16, 25)
Adding Filters
You can add filters within a for loop using an if clause to control which elements should be included in the iteration.
Example: Filtering Even Numbers
for
n <- 1 to 10
if n % 2 == 0
do
println(n)
This prints even numbers between 1 and 10.
Nested Loops
Scala allows nesting of for loops by adding multiple generators separated by semicolons.
Example: Generating Combinations
for
x <- 1 to 3
y <- 1 to 3
do
println(s"($x, $y)")
This prints all combinations of (x, y) pairs where x and y range from 1 to 3.
For-Comprehensions with Guards
Just like simple for loops, for-comprehensions can also include guards.
Example: Filtering and Mapping
val evensSquared =
for
n <- 1 to 10
if n % 2 == 0
yield n * n
println(evensSquared) // Vector(4, 16, 36, 64, 100)
This creates a collection of the squares of even numbers between 1 and 10.