for式

2019年5月5日
1 分

Scala の for 式は、ほかのプログラミング言語よりも機能が豊富だ。まずは簡単な例から見てみよう。

scala> for (x <- 1 to 3) {  
     |     println("x = " + x)  
     | }  
x = 1  
x = 2  
x = 3

見ての通り x1 から 3 まで繰り返しているけど、このカッコの中の x <- 1 to 3 をジェネレータと呼ぶ。1 to 31 から 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

今度の例では xy のジェネレータを使っている。1 until 3 というのは 1 から 23を含まない)の範囲を表している。

ジェネレータには条件を付けることができる。次の例では、xy が等しくない場合だけを抽出している。

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 と呼ぶことがある。