Skip to content

Instantly share code, notes, and snippets.

@kranthilakum
Last active February 17, 2018 14:19
Show Gist options
  • Save kranthilakum/565c118b8a8c72eeedb930a80002fca5 to your computer and use it in GitHub Desktop.
Save kranthilakum/565c118b8a8c72eeedb930a80002fca5 to your computer and use it in GitHub Desktop.
Scala for Expression

for comprehension or for expression:

val numbers = Seq(1, 2, 3)
// numbers: Seq[Int] = List(1, 2, 3)

# single generator
for(i <- 1 to 3) print(i)
// 123

scala> :paste
// Entering paste mode (ctrl-D to finish)

val result = for {
number <- 1 to 3
} yield number

// Exiting paste mode, now interpreting.
result: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3)

# one generator with one guard (an if condition)
for(i <- 1 to 3 if i < 3) print(i)
// 12

# one generator with one guard, but written in multiple lines
for {
  i <- 1 to 3
  if i < 3
} print(i)
// 12
val fruits = Seq("apple", "mango", "papaya")
// fruits: Seq[String] = List(apple, mango, papaya)

for(fruit <- fruits) println(fruit)
apple
mango
papaya

for(fruit <- fruits) println(fruit.capitalize)
Apple
Mango
Papaya

# multiple generator
# `for loop with yield` - create a new data structure from an existing data structure

val result = for {
  number <- Seq(1, 2, 3)
  frut <- fruits
} yield (number, frut)

// result: Seq[(Int, String)] = List((1,apple), (1,mango), (1,kiwi), (2,apple), (2,mango), (2,kiwi), (3,apple), (3,mango), (3,kiwi))

scala> val result = for (fruit <- fruits) yield { fruit.capitalize }
// result: Seq[String] = List(Apple, Kiwi, Banana)

scala> val result = for (fruit <- fruits) yield { fruit.length }
// result: Seq[Int] = List(5, 4, 6)

# Note that `for loop with yield` is the same as a basic map
val result = fruits.map(_.capitalize)
// result: Seq[String] = List(Apple, Kiwi, Banana)

# counter in `for loop`
for (i <- 0 until fruits.length) {
 println(s"$i is ${fruits(i)}")
}
0 is apple
1 is kiwi
2 is banana

# using zipWithIndex if zero-based counter
for( (fruit, count) <- fruits.zipWithIndex ) {
 println(s"${count} is ${fruit}")
}
0 is apple
1 is kiwi
2 is banana

# Beware: zipWithIndex creates a new sequence from the existing sequence, 
# Call view before invoking zipWithIndex e.g. fruits.view.zipWithIndex
# zipWithIndex counter starts at 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment