3.4. Creating a for Comprehension (for/yield Combination)

Problem

You want to create a new collection from an existing collection by applying an algorithm (and potentially one or more guards) to each element in the original collection.

Solution

Use a yield statement with a for loop and your algorithm to create a new collection from an existing collection.

For instance, given an array of lowercase strings:

scala> val names = Array("chris", "ed", "maurice")
names: Array[String] = Array(chris, ed, maurice)

you can create a new array of capitalized strings by combining yield with a for loop and a simple algorithm:

scala> val capNames = for (e <- names) yield e.capitalize
capNames: Array[String] = Array(Chris, Ed, Maurice)

Using a for loop with a yield statement is known as a for comprehension.

If your algorithm requires multiple lines of code, perform the work in a block after the yield keyword:

scala> val lengths = for (e <- names) yield {
     |   // imagine that this required multiple lines of code
     |   e.length
     | }
lengths: Array[Int] = Array(5, 2, 7)

Except for rare occasions, the collection type returned by a for comprehension is the same type that you begin with. For instance, if the collection you’re looping over is an ArrayBuffer:

var fruits = scala.collection.mutable.ArrayBuffer[String]()
fruits += "apple"
fruits += "banana"
fruits += "orange"

the collection your loop returns will also be an ArrayBuffer:

scala> val out = for (e <- fruits) yield e.toUpperCase out: scala.collection.mutable.ArrayBuffer[java.lang.String] ...

Get Scala Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.