Scala For Comprehensions
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.
Please Login to comment...