Scalaの配列とリスト

 

こんにちはKUJIRAです。今日はScalaの配列とリストについて書きます。Scalaの配列にはJavaと同じようにArrayやListなどがあります。

 

まずはArrayについてやります。配列の定義は以下のようになります。

 

scala> val helloString = new Array[String](3)

scala> helloString(0) = "Hello"

scala> helloString(1) = " "

scala> helloString(2) = "world!"

scala> for (i <- 0 to 2)

scala>    | println(helloString)

scala>

 

この配列を使ったソースを見れば分かりますが、変数の宣言は「val」なので値の上書きはできないはずですが、各要素には値を入れられます。要は値を上書きしているのです。

 

これはどういうことかというと変数「helloString」にはString配列の参照が代入されています。なので「helloString」の配列への参照は変えられないが、参照している配列の値は変えられるということです。

 

配列初期化には上のように空のインスタンスを入れる場合もありますが、次のように値の入ったインスタンスを入れることもできます。

 

scala> val helloString2 = Array("Hello", " ", "world!")

scala> helloString2.foreach(arg => println(arg))

scala>

 

どちらを使うかはプログラム次第ですのでこれら二つの方法は頭に入れておいた方がいいです。以上が配列となります。

 

次にリストを見ます。

 

リストと配列の最大の違いは要素の値を上書きできるかできないかです。配列は参照先の要素は上書きできました。しかしリストは一度初期化されてしまうと、そのあとの要素は値の上書きができません。

 

scala> val helloString3 = List("Hello", " ", "world!")

scala> helloString3.foreach(arg => print(arg))
Hello world!

scala> helloString3(0) = "Konnitchiwa"
:3: error: value update is not a memberof List[java.lang.String]
              testList3(0) = "Konnitchiwa"
              ^

scala>

 

このように要素の値を上書きしようとするとエラーになります。updateというメソッドがメンバーにないって怒られます。なんのことかというと配列の要素を上書きするときに

 

scala> helloString2(0) = "Konnitchiwa"

 

としますが、これはこういう風に書き換えられます。

 

scala> helloString2.update(0, "Konnitchiwa")

 

ここから分かるように、配列の要素書き換えはupdateメソッドを利用しての値書き換えに置き換えてコンパイルされます。つまり配列にはupdateメソッドがメンバにいるが、リストにはupdateメソッドがメンバにいないのです。そのためリストは要素の上書きができないようです。

 

しかし、Listには多くの操作用のメソッドがあります。以下によく使うメソッドを書きます。

 

コード 意味
Nil リストを空にする。
List(), List(値,・・・) リストを渡した値で初期化する。値がない場合は空のリストを作成する。
値::リスト リストの先頭に値を追加する。リスト::リストもできるが、その場合はリストの先頭の要素にリストが代入されるのでリストの連結ではない。
リスト:::リスト リストを連結する。
リスト(添字) 添え字の要素の値を返す。
リスト.count(f) リストの各要素についてfが真となるものの数を返す。
例)
scala> val testList = List(“Hello”, ” “, “world!”)

scala> testList.count(s => s.length > 4)
res0: Int = 2

リスト.drop(数値) 先頭から数値分の要素を削ったリストを返す。
リスト.dropRight(数値) 末尾から数値分の要素を削ったリストを返す。
リスト.exists(f) リストの各要素についてfが真となるものが一つでもある場合trueを返す。
リスト.filter(f) リストの各要素についてfが真となるもので構成されるリストを返す。
リスト.forall(f) リストの各要素全てにおいてfが真の場合trueを返す。
リスト.foreach(変数 => 処理) リストの繰り返しを行う。処理が単一かつ引数が一つのメソッドに限り以下のような記述ができる。
リスト.foreach(処理(引数なし))
例)
scala> val testList = List(1, 2, 3, 4, 5)
scala> testList.foreach(print)
12345
リスト.head リストの先頭要素を返す。
リスト.init リストの末尾の要素を抜いたリストを返す。
リスト.isEmpty リストが空かどうかを調べる。空の場合はtrueを返す。
リスト.last リストの末尾の要素を返す。
リスト.length リストの要素数を返す。
リスト.map(f) リストの各要素についてfの結果を格納するリストを返す。
リスト.mkString(文字列) リストの各要素を引数の文字列で連結した文字列を返す。
リスト.remove(f) リストの各要素についてfの判定が真のものを削除したリストを返す。
リスト.reverse リストの要素を全て逆に並べたリストを返す。
リスト.tail(f) リストの先頭要素を取り除いたリストを返す。

 

他にも多くのメソッドがありますので公式サイトのドキュメントを確認してください。ということで今日はここまでKUJIRAでした。