コレクションのクラス関連図
Traverable : 操作可能なコレクション
→ Iterable : 繰り返し可能なコレクション
→ Set : 重複を含まない集合
→ Map : キーと値のペアの集合
→ Seq : 順序のある集合
→ IndexedSeq : VectorやRangeなど、ランダムアクセス?
→ LinearSeq : Listなど、順次アクセス?
→ Buffer : 遅延評価?
Seq
Range
範囲を持つ数値を表現するクラス。ループ処理やList生成で使える。
Range(start, end, step) あるいは、 until/to と by を使って生成できる。
scala> Range(0, 10, 2)
res5: scala.collection.immutable.Range = Range(0, 2, 4, 6, 8)
scala> 0 to 10 by 2
res6: scala.collection.immutable.Range = Range(0, 2, 4, 6, 8, 10)
scala> 0 until 10 by 2
res7: scala.collection.immutable.Range = Range(0, 2, 4, 6, 8)
生成される範囲が違うところに注意が必要。
to/until はfor文で使うと使いやすい。
scala> for (i <- 1 to 3) { println("id:" + i) }
id:1
id:2
id:3
toListでList型に変換することもできる。
scala> (1 to 10).toList
res15: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
List
生成
要素同士を連結するデータ構造のリスト
順次アクセスや再帰呼び出しに強い
ランダムアクセスは遅い
ファクトリメソッドや :: を利用して生成する。
:: は既存のリストに要素を連結するメソッドなので、元となる空リスト( Nil ) が必要
scala> List("taro","jiro","hoge")
res19: List[String] = List(taro, jiro, hoge)
scala> "taro"::"jiro"::"hoge"::Nil
res21: List[String] = List(taro, jiro, hoge)
Listに対する基本操作
先頭に要素追加 ( :: / +: )
scala> 3 +: (1 to 5).toList
res1: List[Int] = List(3, 1, 2, 3, 4, 5)
scala> 3 :: (1 to 5).toList
res2: List[Int] = List(3, 1, 2, 3, 4, 5)
末尾に要素追加 ( *:+)
scala> (1 to 5).toList :+ 6
res5: List[Int] = List(1, 2, 3, 4, 5, 6)
List同士を連結 ( ::: )
scala> (1 to 5).toList ::: (6 to 10).toList
res19: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
:: で連結すると入れ子になってしまう。
scala> (1 to 5).toList :: (6 to 10).toList
res21: List[Any] = List(List(1, 2, 3, 4, 5), 6, 7, 8, 9, 10)
インデックス指定で取得
scala> (1 to 5).toList(3)
res3: Int = 4
一部を取得
head : 先頭
last : 末尾
init : 末尾以外
tail : 先頭以外
slice : 範囲指定
scala> (1 to 5).toList.head
res7: Int = 1
scala> (1 to 5).toList.last
res8: Int = 5
scala> (1 to 5).toList.init
res10: List[Int] = List(1, 2, 3, 4)
scala> (1 to 5).toList.tail
res9: List[Int] = List(2, 3, 4, 5)
scala> (1 to 5).toList.slice(2,4)
res13: List[Int] = List(3, 4)
要素数
size : 要素数
isEmpty/nonEmpty : 空かどうか判断
scala> (1 to 5).toList.size
res14: Int = 5
scala> (1 to 5).toList.isEmpty
res15: Boolean = false
scala> (1 to 5).toList.nonEmpty
res17: Boolean = true
ソート
逆順にする。
scala> (1 to 10).toList.reverse
res13: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
ソート
scala> List(3,1,4,5).sorted
res15: List[Int] = List(1, 3, 4, 5)
filter
引数に判定式を渡すことで、要素の削除ができる。
scala> (1 to 10).toList.filter(_ % 2 == 0)
res24: List[Int] = List(2, 4, 6, 8, 10)
scala> (1 to 10).toList.filterNot(_ % 2 == 0)
res25: List[Int] = List(1, 3, 5, 7, 9)
foreach
リストの要素を繰り返し処理する。
scala> (1 to 3).toList.foreach( e => println("id:" + e) )
id:1
id:2
id:3
zipWithIndex
リストを添え字付きのタプルに変換する。
scala> List("taro","jiro").zipWithIndex
res0: List[(String, Int)] = List((taro,0), (jiro,1))
繰り返し処理で添字が必要になる場合などに使える。
scala> List("taro","jiro").zipWithIndex.foreach{ case(e:String,i:Int) => println("%d:%s".format(i,e)) }
0:taro
1:jiro
map/collect
リストの内容を変換する。
scala> List("taro","jiro").map{ "[" + _ + "]" }
res5: List[String] = List([taro], [jiro])
collectを利用するとcaseの条件に一致した要素のみ抽出できる。
以下の例はString型のみ文字列変換を行っている。
scala> List(1,"taro",2,"jiro").collect{ case(e:String) => "[" + e + "]" }
res9: List[String] = List([taro], [jiro])
reduce/fold
リストに対して集計処理を行う。
初期値なし : reduceLeft/reduceRight
初期値あり : foldLeft/foldRight
scala> (1 to 10).toList.reduceLeft{ _ + _ }
res5: Int = 55
scala> (1 to 10).toList.foldLeft(1){ _ + _ }
res6: Int = 56
内部的には (((1+2)+3)+4)...という処理を行っている。
zip/unzip
リスト同時を並列に結合して、ペアのリストを作る。
scala> (1 to 10 by 2).toList.zip( 2 to 10 by 2 )
res9: List[(Int, Int)] = List((1,2), (3,4), (5,6), (7,8), (9,10))
Map
タプル型を渡すことでMapを生成できる。
scala> Map( ("taro", "hoge"),("jiro", "piyo") )
res14: scala.collection.immutable.Map[String,String] = Map(taro -> hoge, jiro -> piyo)
Map(key->value) 形式でも生成可能。
-> はタプルを生成するメソッド
getメソッドで値を取得
scala> val map = Map("taro"->"hoge", "jiro"->"piyo")
map: scala.collection.immutable.Map[String,String] = Map(taro -> hoge, jiro -> piyo)
scala> map.get("taro")
res11: Option[String] = Some(hoge)
Map.getの戻り値はOption型、キーが存在しない場合はNoneとなる。
scala> map.get("naiyo")
res12: Option[String] = None