Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Scala For Comprehensions

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

Comprehensions have the structure for (enumerators) yield e, wherever enumerators refers to a semicolon-separated list of enumerators. Enumerator is either a generator that introduces new variables, or it’s a filter. A comprehension evaluates the body e for every binding generated by the enumerators and returns a sequence of those values.

These definitions lead us to the for comprehension ideas of generators, filters, and definitions. A Scala for comprehension will contain the subsequent 3 expressions:

  • Generators
  • Filters
  • Definitions

Syntax:

for {
    b <- books             // generator
    n = b.name               // definition
    if (n startsWith "To")   // filter
} yield

 
Generators -
Generators have below form:

pattern <- expression

For example b <- books In this expression the value b iterates over all of the elements contained in books.
Below are two more things about generators -

  • Each for comprehension begins with a generator.
  • for comprehensions will be multiple generators.

Definitions -

For comprehension definitions have below syntax:

pattern = expression

For example n = b.name the variable n is bound to the value b.name. That statement has a similar result as writing this code outside of a for comprehension. val n = b.name

Filters -

For comprehension filters have below form:

if (expression)

Expression have the type Boolean. Filters drop all elements from the iteration that which expression returns false, as like given code. For example if (n startsWith "Ca") any value n that does not start with the string Ca will be dropped during the iteration process.

Let's discuss some examples.

Example #1: With yield




// Scala program of for comprehensions
  
// Creating object 
object Geeks 
  
    // Main method 
    def main(args: Array[String]) 
    
        // Creating case class    
        case class Language(name: String, article: Int)
          
        val LanguageBase = List(Language("Scala", 26),
                                Language("Csharp", 32),
                                Language("Perl", 42),
                                Language("Java", 22))
          
        // Applying for comprehensions
        // Generator
        // Definition
        val MoreThanTwenty = for (language <- LanguageBase
        if (language.article >=20 && language.article < 30))// Filters
          
         // i.e. add this to a list
          yield language.name 
          
        // Print more than twenty 
        MoreThanTwenty.foreach(name => println(name))
      
    


Output :

Scala
Java

In above example, the for loop used with a yield statement actually creates a List. Because we said yield language.name, it’s a List[String]. language <- LanguageBase is our generator and if (language.article >=20 && language.article < 30) could be a guard that filters out article those don't seem to be in between 20 to 30.
 
Example #2: Without yield

We can omit yield in comprehension. In that case, comprehension will return Unit. This can be helpful just in case we would like to perform side-effects. Here’s a program like the above one, without using yield.




// Scala program to print Hello, Geeks! 
// by using object-oriented approach 
  
// creating object 
object Geeks { 
  
// Main method 
def main(args: Array[String]) 
      
def check(a: Int) =
   for (i <- 0 until 4;
        j <- 0 until 4 if i * j >= a)
   println(s"($i, $j)")
  
check(4)


Output:

(2, 2)
(2, 3)
(3, 2)
(3, 3)

In above example, a = 4. In the first iteration, i = 0 and j = 0 so i * j is not greater than equal to a and therefore nothing is yielded. j gets incremented 3 more times before i gets incremented to 1.

My Personal Notes arrow_drop_up
Last Updated : 19 May, 2019
Like Article
Save Article
Similar Reads