Scala の for 式は、ほかのプログラミング言語よりも機能が豊富だ。まずは簡単な例から見てみよう。
scala> for (x <- 1 to 3) {
| println("x = " + x)
| }
x = 1
x = 2
x = 3
見ての通り x を 1 から 3 まで繰り返しているけど、このカッコの中の x <- 1 to 3 をジェネレータと呼ぶ。1 to 3 は 1 から 3 まで(3 を含む)の範囲を表す式でこれを順に x に代入するものだ。ジェネレータは複数あってもいい。
scala> for (x <- 1 to 3; y <- 1 until 3) {
| println("x = " + x + " y = " + y)
| }
x = 1 y = 1
x = 1 y = 2
x = 2 y = 1
x = 2 y = 2
x = 3 y = 1
x = 3 y = 2
今度の例では x と y のジェネレータを使っている。1 until 3 というのは 1 から 2(3を含まない)の範囲を表している。
ジェネレータには条件を付けることができる。次の例では、x と y が等しくない場合だけを抽出している。
scala> for (x <- 1 to 3; y <- 1 until 3 if x != y) {
| println("x = " + x + " y = " + y)
| }
x = 1 y = 2
x = 2 y = 1
x = 3 y = 1
x = 3 y = 2
for 式は、コレクションの要素を1つずつたどっていくこともできる。いわゆる foreach のような使い方だ。次の例ではリストの要素を順に出力している。
scala> for (e <- List("A", "B", "C", "D", "E")) {
| println(e)
| }
A
B
C
D
E
さらに、for 式ではコレクションから新しいコレクションを作ることもできる。
scala> for (e <- List("A", "B", "C", "D", "E")) yield {
| "Pre" + e
| }
res5: List[String] = List(PreA, PreB, PreC, PreD, PreE)
ここでのポイントは、ブロック式の前についている yield キーワードだ。yield をつけることで単に繰り返すのではなく、新しいコレクションを作ってくれる。yield キーワードを使ったこの形を for-comprehension と呼ぶことがある。