#Scala Loops
Scala provides various loop structures, including for loops, while loops, and more. Scala's loops have functional programming characteristics, supporting generators, filters, and comprehensions.
#For Loops
#Basic For Loop
object BasicForLoop {
def main(args: Array[String]): Unit = {
// Basic range loop
println("Basic for loop:")
for (i <- 1 to 5) {
println(s"i = $i")
}
println("\nuntil loop (excludes end value):")
for (i <- 1 until 5) {
println(s"i = $i")
}
println("\nStep loop:")
for (i <- 1 to 10 by 2) {
println(s"i = $i")
}
println("\nReverse loop:")
for (i <- 10 to 1 by -1) {
println(s"i = $i")
}
}
}#Iterating Over Collections
object CollectionIteration {
def main(args: Array[String]): Unit = {
val fruits = List("apple", "banana", "orange", "grape")
val numbers = Array(1, 2, 3, 4, 5)
println("Iterating over list:")
for (fruit <- fruits) {
println(s"Fruit: $fruit")
}
println("\nIterating over array:")
for (num <- numbers) {
println(s"Number: $num")
}
println("\nIterating with index:")
for ((fruit, index) <- fruits.zipWithIndex) {
println(s"Number ${index + 1} fruit: $fruit")
}
println("\nUsing indices:")
for (i <- fruits.indices) {
println(s"Index $i: ${fruits(i)}")
}
}
}#Nested For Loops
object NestedForLoop {
def main(args: Array[String]): Unit = {
println("Nested for loop - Multiplication table:")
for (i <- 1 to 3) {
for (j <- 1 to 3) {
print(s"${i * j}\t")
}
println()
}
println("\nNested loop using semicolons:")
for (i <- 1 to 3; j <- 1 to 3) {
println(s"($i, $j) = ${i * j}")
}
println("\nThree-level nesting:")
for {
x <- 1 to 2
y <- 1 to 2
z <- 1 to 2
} {
println(s"($x, $y, $z)")
}
}
}#For Loop with Conditions
object ConditionalForLoop {
def main(args: Array[String]): Unit = {
val numbers = 1 to 20
println("Even numbers:")
for (num <- numbers if num % 2 == 0) {
println(num)
}
println("\nNumbers divisible by 3:")
for (num <- numbers if num % 3 == 0) {
println(num)
}
println("\nMultiple conditions:")
for {
num <- numbers
if num % 2 == 0
if num > 10
} {
println(s"Greater than 10 even number: $num")
}
println("\nString filtering:")
val words = List("hello", "world", "scala", "programming", "fun")
for (word <- words if word.length > 4) {
println(s"Long word: $word")
}
}
}#For Comprehension
object ForComprehension {
def main(args: Array[String]): Unit = {
val numbers = 1 to 10
// Generate new collection
val squares = for (num <- numbers) yield num * num
println(s"Square numbers: $squares")
val evenSquares = for {
num <- numbers
if num % 2 == 0
} yield num * num
println(s"Even squares: $evenSquares")
// String processing
val words = List("hello", "world", "scala")
val upperWords = for (word <- words) yield word.toUpperCase
println(s"Uppercase words: $upperWords")
// Complex comprehension
val coordinates = for {
x <- 1 to 3
y <- 1 to 3
if x != y
} yield (x, y)
println(s"Coordinate pairs (x != y): $coordinates")
// Nested collection processing
val matrix = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
val flattenedDoubled = for {
row <- matrix
element <- row
} yield element * 2
println(s"Flattened and doubled: $flattenedDoubled")
}
}#While Loops
#Basic While Loop
object BasicWhileLoop {
def main(args: Array[String]): Unit = {
var i = 1
println("While loop:")
while (i <= 5) {
println(s"i = $i")
i += 1
}
// Calculate factorial
var n = 5
var factorial = 1
var counter = 1
while (counter <= n) {
factorial *= counter
counter += 1
}
println(s"$n! = $factorial")
}
}#Do-While Loop
object DoWhileLoop {
def main(args: Array[String]): Unit = {
var i = 1
println("Do-while loop:")
do {
println(s"i = $i")
i += 1
} while (i <= 5)
// Example that executes at least once
var input = 0
do {
println("Please enter a positive number:")
input = scala.io.StdIn.readInt()
if (input <= 0) {
println("Invalid input, please try again!")
}
} while (input <= 0)
println(s"You entered positive number: $input")
}
}#Loop Control
#Break and Continue (using Breaks)
import scala.util.control.Breaks._
object LoopControl {
def main(args: Array[String]): Unit = {
println("Using break:")
breakable {
for (i <- 1 to 10) {
if (i == 6) break()
println(s"i = $i")
}
}
println("\nUsing continue (skip even numbers):")
for (i <- 1 to 10) {
breakable {
if (i % 2 == 0) break() // Equivalent to continue
println(s"Odd number: $i")
}
}
println("\nBreak in nested loops:")
breakable {
for (i <- 1 to 5) {
for (j <- 1 to 5) {
if (i * j > 10) break()
println(s"$i * $j = ${i * j}")
}
}
}
}
}#Labeled Break
import scala.util.control.Breaks._
object LabeledBreak {
def main(args: Array[String]): Unit = {
println("Labeled break:")
outer: breakable {
for (i <- 1 to 5) {
inner: breakable {
for (j <- 1 to 5) {
if (i == 3 && j == 3) {
println(s"Breaking outer loop at ($i, $j)")
break(outer)
}
println(s"($i, $j)")
}
}
}
}
println("Outer loop ended")
}
}#Functional Loop Alternatives
#Using Higher-Order Functions
object FunctionalLoops {
def main(args: Array[String]): Unit = {
val numbers = List(1, 2, 3, 4, 5)
println("Using foreach:")
numbers.foreach(num => println(s"Number: $num"))
println("\nUsing map:")
val doubled = numbers.map(_ * 2)
println(s"Doubled: $doubled")
println("\nUsing filter:")
val evens = numbers.filter(_ > 2)
println(s"Evens: $evens")
println("\nUsing reduce:")
val sum = numbers.reduce(_ + _)
println(s"Sum: $sum")
println("\nUsing fold:")
val product = numbers.fold(1)(_ * _)
println(s"Product: $product")
println("\nUsing zipWithIndex:")
numbers.zipWithIndex.foreach { case (value, index) =>
println(s"Index $index: $value")
}
}
}#Recursion as Loop Alternative
object RecursiveLoops {
// Recursive factorial
def factorial(n: Int): Int = {
if (n <= 1) 1
else n * factorial(n - 1)
}
// Tail recursive factorial
def factorialTailRec(n: Int): Int = {
@annotation.tailrec
def loop(n: Int, acc: Int): Int = {
if (n <= 1) acc
else loop(n - 1, n * acc)
}
loop(n, 1)
}
// Recursive list traversal
def printList[T](list: List[T]): Unit = list match {
case Nil => println("List end")
case head :: tail =>
println(s"Element: $head")
printList(tail)
}
// Recursive Fibonacci sequence
def fibonacci(n: Int): Int = {
if (n <= 1) n
else fibonacci(n - 1) + fibonacci(n - 2)
}
// Tail recursive Fibonacci
def fibonacciTailRec(n: Int): Int = {
@annotation.tailrec
def loop(n: Int, prev: Int, curr: Int): Int = {
if (n == 0) prev
else loop(n - 1, curr, prev + curr)
}
loop(n, 0, 1)
}
def main(args: Array[String]): Unit = {
println(s"5! = ${factorial(5)}")
println(s"5! (tail recursive) = ${factorialTailRec(5)}")
val list = List(1, 2, 3, 4, 5)
printList(list)
println(s"Fibonacci number at position 10: ${fibonacci(10)}")
println(s"Fibonacci number at position 10 (tail recursive): ${fibonacciTailRec(10)}")
}
}#Practical Examples
#Number Guessing Game
import scala.util.Random
import scala.io.StdIn
object NumberGuessingGame {
def main(args: Array[String]): Unit = {
val random = new Random()
val targetNumber = random.nextInt(100) + 1
var attempts = 0
var guessed = false
println("Welcome to the number guessing game!")
println("I'm thinking of a number between 1 and 100, can you guess it?")
while (!guessed && attempts < 10) {
print("Please enter your guess: ")
val guess = StdIn.readInt()
attempts += 1
if (guess == targetNumber) {
println(s"Congratulations! You guessed it correctly on attempt $attempts!")
guessed = true
} else if (guess < targetNumber) {
println("Too low!")
} else {
println("Too high!")
}
if (!guessed && attempts < 10) {
println(s"You have ${10 - attempts} more chances")
}
}
if (!guessed) {
println(s"Game over! The correct answer was $targetNumber")
}
}
}#Matrix Operations
object MatrixOperations {
def printMatrix(matrix: Array[Array[Int]]): Unit = {
for (row <- matrix) {
for (element <- row) {
print(s"$element\t")
}
println()
}
}
def createMatrix(rows: Int, cols: Int): Array[Array[Int]] = {
val matrix = Array.ofDim[Int](rows, cols)
var counter = 1
for (i <- matrix.indices) {
for (j <- matrix(i).indices) {
matrix(i)(j) = counter
counter += 1
}
}
matrix
}
def transposeMatrix(matrix: Array[Array[Int]]): Array[Array[Int]] = {
val rows = matrix.length
val cols = matrix(0).length
val transposed = Array.ofDim[Int](cols, rows)
for (i <- matrix.indices; j <- matrix(i).indices) {
transposed(j)(i) = matrix(i)(j)
}
transposed
}
def main(args: Array[String]): Unit = {
println("Creating 3x4 matrix:")
val matrix = createMatrix(3, 4)
printMatrix(matrix)
println("\nTransposed matrix:")
val transposed = transposeMatrix(matrix)
printMatrix(transposed)
}
}#Prime Number Generator
object PrimeGenerator {
def isPrime(n: Int): Boolean = {
if (n < 2) return false
if (n == 2) return true
if (n % 2 == 0) return false
var i = 3
while (i * i <= n) {
if (n % i == 0) return false
i += 2
}
true
}
def generatePrimes(limit: Int): List[Int] = {
val primes = for {
num <- 2 to limit
if isPrime(num)
} yield num
primes.toList
}
def sieveOfEratosthenes(limit: Int): List[Int] = {
val isPrime = Array.fill(limit + 1)(true)
isPrime(0) = false
if (limit >= 1) isPrime(1) = false
for (i <- 2 to math.sqrt(limit).toInt) {
if (isPrime(i)) {
for (j <- i * i to limit by i) {
isPrime(j) = false
}
}
}
(for (i <- isPrime.indices if isPrime(i)) yield i).toList
}
def main(args: Array[String]): Unit = {
val limit = 50
println(s"Generate primes within $limit using trial division:")
val primes1 = generatePrimes(limit)
println(primes1.mkString(", "))
println(s"\nGenerate primes within $limit using Sieve of Eratosthenes:")
val primes2 = sieveOfEratosthenes(limit)
println(primes2.mkString(", "))
}
}#Performance Considerations
- For comprehension vs imperative loops: For comprehensions are more functional but may have performance overhead
- Tail recursion optimization: Use
@tailrecannotation to ensure tail recursion optimization - Avoid nested loops: Consider functional methods like
flatMap - Use View: For large collections, use
viewfor lazy evaluation
object PerformanceConsiderations {
def main(args: Array[String]): Unit = {
val largeRange = 1 to 1000000
// Use view for lazy evaluation
val result = largeRange.view
.filter(_ % 2 == 0)
.map(_ * 2)
.take(10)
.toList
println(s"First 10 even numbers doubled: $result")
}
}Mastering loop structures is essential for writing efficient Scala programs, and learning to use functional programming alternatives when appropriate is also important.