【Scala】リストのリスト、対と組

【Scala】列、集合、マップ - seconの日記の続き

Scalaでリスト処理を見ながらお勉強
今回は8.リストのリスト~9.対と組


リストのリスト

要素がリストのリスト。記述方法はこう

scala> var list = List(List(2,1,4),List(3,5,6),List(7,1,2))
list: List[List[Int]] = List(List(2, 1, 4), List(3, 5, 6), List(7, 1, 2))



勿論変数を要素にできる

scala> var a =List(2,1,4);var b = List(3,5,6)
a: List[Int] = List(2, 1, 4)
b: List[Int] = List(3, 5, 6)

scala> var list = List(a,b)
list: List[List[Int]] = List(List(2, 1, 4), List(3, 5, 6))



リストのリストのリストも作れる

scala> var list2 = List(List(List(2,1),List(3,1)),List(List(4,3),List(2,3)))
list2: List[List[List[Int]]] = List(List(List(2, 1), List(3, 1)), List(List(4, 3), List(2, 3)))

見づらすぎワロタ。
もし使うことがあるなら変数を要素にしたほうが良さそう


リストのリストに関数を使ってみる。

それぞれの要素に+1

scala> list.map(_.map(_+1)) //mapを2個使う点に注意
res: List[List[Int]] = List(List(3, 2, 5), List(4, 6, 7))

それぞれの最後の要素を除いたリストを求めるたいならこう

scala> list.map(_.init)
res: List[List[Int]] = List(List(2, 1), List(3, 5))

リストの中のリストの要素を求めたいとき

scala> list(1)(2)
res: Int = 6

applyを省略しないならlist.apply(1).apply(2)

リストの追加

scala> list ++ List(List(4,6,2))
res: List[List[Int]] = List(List(2, 1, 4), List(3, 5, 6), List(4, 6, 2))



・flatMap
リストのリストに対して、連結とmapを一気に行うことが出来る。

例えば、+1をして連結。

scala> list.flatMap(_.map(_ + 1))
res: List[Int] = List(3, 2, 5, 4, 6, 7)

偶数リストを返す

scala> list.flatMap(_.filter(_ % 2 == 0))
res: List[Int] = List(2, 4, 6)


恒等関数 x => x で単純なリストの連結。flattenメソッドで同じことが可能

scala> list.flatMap(x => x)
res: List[Int] = List(2, 1, 4, 3, 5, 6)

scala> list.flatten
res: List[Int] = List(2, 1, 4, 3, 5, 6)



整数 i と j がそれぞれ1から3まで変化する時、10*i+jを要素とするリストを返す

scala> (1 to 3).flatMap(i => (1 to 3).map(j => 10*i+j))
res: IndexedSeq[Int] = Vector(11, 12, 13, 21, 22, 23, 31, 32, 33)

下はforを用いた同じ使い方。内部的にはflatMapに変換される

scala> for(i<-1 to 3;j<-1 to 3)yield 10*i+j
res: IndexedSeq[Int] = Vector(11, 12, 13, 21, 22, 23, 31, 32, 33)


対と組

ListやSeqは長さが任意のデータ列なのに対し、組(Tuple)は長さが固定のデータ列である
各要素のデータ型は異なっててもOK
タプルは要素数iに応じてTuple(i)というクラスが用意されている(要素数が4ならTuple4.)

記述法はこう

scala> var Tuple = ("a",1.4,"asd") 
Tuple: (String, Double, String) = (a,1.4,asd)

要素を取り出す場合

scala> Tuple._2
res68: Double = 1.4

代入ならこうやって取り出すことも出来る

scala> var(a,b,c) = Tuple
a: String = a
b: Double = 1.4
c: String = asd



要素が2個のタプルは、「Pair」という特別なクラスがある。
また、「->」を使った特別な書き方もある

scala> var Pair = 1 -> 2
Pair: (Int, Int) = (1,2)

また、要素が3個のタプルにも「Triple」という特別なクラスがある。


要素数が23以上になるとerrorになるらしい

scala> (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) //要素数22
res: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) = (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)

scala> (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) //要素数23
<console>:8: error: object Tuple23 is not a member of package scala
              (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
              ^