Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

scala

What are For comprehensions in Scala?

Adnan Abbas

Comprehensions is a construct in Scala which allows us to evaluate certain expressions. The For Comprehension has the form for (enumerators) yield e, where enumerators refer to a semi-colon separated list of enumerators.

An enumerator can either be a generator that iterates the list or a filter. A comprehension evaluates the body e for each result generated by the enumerator and returns a list of these values.

Examples

case class Player(name: String, matchesPlayed: Int)
val players = List(
  Player("DeVilliers",22),
  Player("Afridi", 45),
  Player("Steven",32),
  Player("Kepler",100)
)

val amateurPlayers =
  for (player <- players if player.matchesPlayed >=20 && player.matchesPlayed < 40)
  yield player.name  // i.e. add this to a list

amateurPlayers.foreach(println)  

In the code above, we create a Player class that contains information about a player’s name and the number of matches they have played. Then, we create a list of players in line 2. In line 10, we use the For Comprehension and a generator and filter to print the names of amateur players who have played matches between 20 and 40. player <- players is a list, and we filter out the players based on the condition described. The yield operation collects the result as List[String] as player.name is a String.

Here is another example in which we use two generators:

def equalProduct(n: Int, v: Int) =
   for (i <- 0 until n;
        j <- 0 until n if i * j == v)
   yield (i, j)

//The function equalProduct returns a list like [(a,b),(c,d),...]
equalProduct(10, 10) foreach {
  case (i, j) =>
    println(s"($i, $j) ")  
}

//We can see how the program iterates over the two lists without the filter applied.
def withoutFilter(n: Int, v: Int) =
   for (i <- 0 until n;
        j <- 0 until n )
   yield (i, j)
println("Normal iteration (without filters)")
withoutFilter(10,10) foreach {
  case (i, j) =>
    println(s"($i, $j) ")  
}

In this example, we have created a function equalProduct, which computes all pairs of numbers between 0 and n-1 whose product equals a given value v. As line 3 suggests, we have created two generators, i and j, which increments by 1 until n. Then, we apply the filter as required. To print the pairs, we iterate over the list in line 7, destructure each element as (i,j) and print it.

To illustrate how the generators i and j take steps, we have also produced the list returned by the function without any filters. The output shows that one of the generators increments till n-1 while the other remains constant. After the first generator reaches n-1, the other generator increments by 1.

RELATED TAGS

scala

CONTRIBUTOR

Adnan Abbas
Copyright ©2022 Educative, Inc. All rights reserved
RELATED COURSES

View all Courses

Keep Exploring