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.
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 listamateurPlayers.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.
Free Resources