Scala 例 for Listの読み込み + Listの生成
Scalaのforも、やっぱりListをイテレートするのにつかう。
くわえて、Listをつくる機能もある。
このページはforだけ。Listそのものについては、こちら
- 別の日記
- Scala 例 List - kaishitaeiichiの日記
- Scaladoc
- Scala Standard Library 2.12.8 - scala.collection.immutable.List
ふつうに見えるfor
以下、REPLで改行したときの記号|がはいっているからちょっと見にくくなるけど、
scala> for ( i <- 1 to 4) { | println(i) | } 1 2 3 4 scala> for ( i <- 1 until 4) { | println(i) | } 1 2 3
実際は、Scala Standard Library 2.12.8 - scala.collection.immutable.Rangeをiterate?しているようだ。
scala> 1 to 4 res11: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4) scala> 1 until 4 res12: scala.collection.immutable.Range = Range(1, 2, 3)
どうやら、for ( i <- 1 to 4) という見た目で勘違いしてしまったが、Listのiterate処理そのものということらしい。
上の例では、iなんてつかっているけれど、Scalaのforは、Javaでいったら、
for(int i = 0; i < list.size(); i++) { A a = list.get(i); }
こっちじゃなくて、
for(A a : list) {
}
こっちだ。
おなじみのやつをforループしてみよう。
scala> val list = List("a", "b", "c") list: List[java.lang.String] = List(a, b, c) scala> for( e <- list) { | println(e) | } a b c scala> val map = Map(1 -> "a", 2 -> "b", 3 -> "c") map: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a, 2 -> b, 3 -> c) scala> for (e <- map) { | println(e) | } (1,a) (2,b) (3,c) scala> val tuple = (1, "a", 'x) tuple: (Int, java.lang.String, Symbol) = (1,a,'x) scala> for( e <- tuple.productIterator ) { | println(e) | } 1 a 'x
リスト内包表記
forループを使って、あるListからべつのListをつくるのは、Javaでもよくやる。
Scalaで、ListからListを生成するのは、Scala Standard Library 2.12.8 - scala.collection.immutable.Listのmapメソッドを真っ先におぼえて、一番つかっている気がする。
Scalaのforは、いわゆるリスト内包表記がつかえる。forを使って、Listを生成することができる。for + yield 生成するListの要素という書き方をする。
そういえば、HaskellやPythonにも、リスト内包表記はあったなあ。
scala> for ( x <- 1 to 13 ) yield x res20: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
Listといいつつ、Vectorになってしまった。
forにListを2つ書けば、直積をつくることもできる。
scala> object Suit extends Enumeration { val HEART, DIA, SPADE, CLUB = Value} defined module Suit scala> for (suit <- Suit.values; cardNo <- 1 to 13) yield (suit, cardNo) res10: scala.collection.immutable.Set[(Suit.Value, Int)] = Set((HEART,3), (CLUB,4), (CLUB,12), (DIA,1), (HEART,5), (SPADE,11), (CLUB,3), (HEART,4), (CLUB,5), (DIA,11), (CLUB,7), (DIA,3), (SPADE,12), (HEART,12), (SPADE,8), (SPADE,10), (SPADE,6), (DIA,2), (SPADE,3), (DIA,13), (SPADE,4), (CLUB,11), (CLUB,6), (SPADE,5), (SPADE,1), (DIA,12), (SPADE,9), (SPADE,2), (HEART,1), (HEART,8), (CLUB,8), (CLUB,13), (DIA,7), (DIA,6), (DIA,8), (CLUB,9), (HEART,11), (HEART,9), (CLUB,10), (SPADE,7), (CLUB,2), (HEART,10), (HEART,6), (HEART,7), (CLUB,1), (DIA,9), (SPADE,13), (HEART,2), (DIA,4), (HEART,13), (DIA,5), (DIA,10))
Listといいつつ、Setになってしまった。(suit, cardNo)はタプルだから、タプルのSet
ちょっと整理して、出力すると、
scala> (for (suit <- Suit.values; cardNo <- 1 to 13) yield (suit, cardNo)).toList.sorted foreach { | card => card._2 match { | case 13 => println(card) | case _ => print(card) | } | } (HEART,1)(HEART,2)(HEART,3)(HEART,4)(HEART,5)(HEART,6)(HEART,7)(HEART,8)(HEART,9)(HEART,10)(HEART,11)(HEART,12)(HEART,13) (DIA,1)(DIA,2)(DIA,3)(DIA,4)(DIA,5)(DIA,6)(DIA,7)(DIA,8)(DIA,9)(DIA,10)(DIA,11)(DIA,12)(DIA,13) (SPADE,1)(SPADE,2)(SPADE,3)(SPADE,4)(SPADE,5)(SPADE,6)(SPADE,7)(SPADE,8)(SPADE,9)(SPADE,10)(SPADE,11)(SPADE,12)(SPADE,13) (CLUB,1)(CLUB,2)(CLUB,3)(CLUB,4)(CLUB,5)(CLUB,6)(CLUB,7)(CLUB,8)(CLUB,9)(CLUB,10)(CLUB,11)(CLUB,12)(CLUB,13)