List
ScalaではArrayを使う代わりにListやVectorと言ったデータ構造がよく使われます。
Listの特徴はimmutableであることです。
中身を変更できないデータ構造(永続データ構造とも呼ぶ)はScalaがサポートいている関数型プログラミングにとって重要な要素です。
Listは先頭へのアクセスは高速な反面、要素へのランダムアクセスや末尾へのデータ挿入はListの長さに比例した時間がかかります。
Listの末尾に要素を追加するような遅いプログラムを書いてしまうことがあるので注意してください。
Listは次のように宣言できます。
val lst = List(pram1, pram2, pram3, ..., pramN)
ScalaではからのListを表すのに"Nil"というものを使います。
このNilはRubyのNilとは違い、デフォルトでスコープに入っているだけのただのオブジェクトです。
ListにはすでにあるListの先頭に要素を接着するメソッド::
(コンスと読む)があります。
val a1 = 1 :: Nil
val a2 = 2 :: a1
val a3 = 3 :: a2
// 接着したい要素を::を破産でListの前に書くことでListの先頭に要素を接着することができます
メソッド名の最後が":"で終わる場合、被演算子の前と後ろをひっくり返して右結合で呼び出します。
要するに":"で終わるメソッドは右辺のメソッドとして呼び出されるということです。
param1 :: param2 :: param3 //実際には次のように呼びだされます param3.::(param2).::(param1)
List同士の結合には++
メソッドを使います。
大きなList同士の結合は計算量が大きくなるので注意してください
val lstJoin = List(1, 2) ++ List(3, 4, 5)
mkStringメソッドは非常に頻繁に使用されます。このメソッドは引数によって多重定義されており、3つのバージョンがあります。
引数 | 宣言 | 効果 |
---|---|---|
なし | mkString() | リストの左から順に結合した文字列を返す |
1つ | mkString("sep") | 引数にセパレータ文字列を取り、リストの各要素を引数で区切って左から順に結合した文字列を返す |
3つ | mkString("start", "sep", "end") | startとendに囲まれ、かつsepで区切られた結合された文字列を返す |
foldLeftメソッドはListにとって非常に基本的なメソッドです。他の様々なメソッドをfoldLeftを使って実装することができます。
構文は次の通りです。
def foldLeftB(f: (B, A) => B): B
この時zがfoldLeftの初期値で、Listを左から辿りながらfを適用していきます。
val foldLeftRes = List(1, 2, 3).foldLeft(0)( (x, y) => x + y)
// これはリストの要素を左から順に「畳み込む」処理をしています
// 左から順に加算をしているので結果は6になります
foldRightメソッドは右から畳み込みを行います。
val foldRightRes = List(1, 2, 3).foldRight(0)( (x, y) => x + y)
mapメソッドは1引数の関数を引数に取り、各要素に関数を適用した結果を返すメソッドです。
val mapList = List(1, 2, 3, 4, 5).map(x => x * 2)
よくあるmapメソッドと同じです
filterメソッドはBoolean型を返す1引数の関数を引数にとり、各要素に関数を適用し、trueになった要素のみを抽出した新たなListをかえします。
val filterList = List(1, 2, 3, 4, 5).filter(x => x % 2 == 1)
// 奇数の要素のみ抽出
findメソッドは、Boolean型を返す1引数の関数を引数に取り、各要素に前から順番に関数を適用し、最初にtrueになった要素をSomeでラッピングした値をOption型として返します。
1つの要素もマッチしなかった場合はNoneをOption型として返します。
今のところOption型は戻り値をラッピングして、値があればSome型をなければNone型を返す型だと思ってください
val findList = List(1, 2, 3, 4, 5).find(x => x % 2 == 1)
takeWhileメソッドは、Boolean型を返す1引数の関数を引数に取り、前から順番に関数を適用し結果がtrueの間のみからなるListを返します。
val takeWhileList = List(1, 2, 3, 4, 5, 6, 7).takeWhile(x => x != 5)
countメソッドは、Boolean型を返す1引数の関数を引数に取り、すべての要素に関数を適用して、trueが返ってきた要素の数を計算します。
val countList = List(1, 2, 3, 4, 5).count(x => x % 2 == 0)
flatMapメソッドは1引数の関数を引数に取り、各要素に関数を適用した結果の要素からなるコレクションを分解してListの要素にして返します。
val flatMapList = List(List(1, 2, 3), List(4, 5, 6) ).flatMap{e => e.map(g => g + 1) }
// ネストしたListの各要素にflatMapの中でmapを用いて、Listの各要素に1を加算したものを平らにして返しています