LoginSignup
65
66

More than 5 years have passed since last update.

Scalaのコレクションとかについて

Last updated at Posted at 2014-03-14

コレクションのクラス関連図

Traverable : 操作可能なコレクション

→ Iterable : 繰り返し可能なコレクション

→ Set : 重複を含まない集合
→ Map : キーと値のペアの集合
→ Seq : 順序のある集合

→ IndexedSeq : VectorやRangeなど、ランダムアクセス?
→ LinearSeq : Listなど、順次アクセス?
→ Buffer : 遅延評価?

Seq

Range

範囲を持つ数値を表現するクラス。ループ処理やList生成で使える。
Range(start, end, step) あるいは、 until/toby を使って生成できる。

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

Set

65
66
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
65
66