web-dev-qa-db-ja.com

リストに要素を追加するScala

Scala 2.10.2。リストを作成し、リストにいくつかの要素を追加し、リストの名前を呼び出したときにリスト内のすべての要素が表示されることを期待しています。かなり奇妙なものを観察しました(私は初心者なので、少なくとも私にとっては奇妙です)以下は、私のsbt consoleでやろうとしたことです

scala> val l = 1.0 :: 5.5 :: Nil
l: List[Double] = List(1.0, 5.5)

scala> l
res0: List[Double] = List(1.0, 5.5)

scala> l ::: List(2.2, 3.7)
res1: List[Double] = List(1.0, 5.5, 2.2, 3.7)

scala> List(l) :+ 2.2
res2: List[Any] = List(List(1.0, 5.5), 2.2)

scala> l
res3: List[Double] = List(1.0, 5.5)

scala> 

最初に、2つの要素(1.0および5.5)を含むリストlを作成しました。 lを呼び出して、期待どおりのものを取得します。 2つの要素。ここで、:::を使用してリストに別の要素を追加しようとしましたが、これは追加した要素の新しいリスト(2.2および3.7)で新しいリストを返しました。私は他の誰かのコードの助けを確認しました: Scalaのリストの最後に要素を追加する 新しいコンストラクト:+を使用します。したがって、この段階で私はすべて満足していますが、lを呼び出すと、予期しない結果が返されます: `res3:List [Double] = List(1.0、5.5) '。

追加した要素はどこにありますか?そして、lを呼び出したときに追加したすべてのものを含む新しいリストを取得できるように、これらの要素を正しく追加するにはどうすればよいですか?

34
Emmanuel

不変リストを使用しています。リストに対する操作は、新しいリストを返します。古いリストは変更されません。これは、別のクラス/メソッドが元のコレクションへの参照を保持し、それが変更されないままであることに依存している場合に非常に役立ちます。次のように、異なる名前のvalを使用できます。

val myList1 = 1.0 :: 5.5 :: Nil 
val myList2 = 2.2 :: 3.7 :: mylist1

または次のように変数を使用します

var myList = 1.0 :: 5.5 :: Nil 
myList :::= List(2.2, 3.7)

これは、次と同等の構文です。

myList = myList.:::(List(2.2, 3.7))

または、次のような可変コレクションのいずれかを使用できます。

val myList = scala.collection.mutable.MutableList(1.0, 5.5)
myList.++=(List(2.2, 3.7))

元の可変リストを変更せず、新しい値を返す以下と混同しないでください。

myList.++:(List(2.2, 3.7))

ただし、パフォーマンスが重要なコードでのみ可変コレクションを使用する必要があります。不変コレクションは、推論と使用がはるかに簡単です。 1つの大きな利点は、不変のListと scala.collection.immutable.Vector が共変であることです。それがまだあなたにとって何を意味していなくても心配しないでください。その利点は、完全に理解しなくても使用できることです。したがって、デフォルトで使用していたコレクションは、実際には scala.collection.immutable.List であり、自動的にインポートされます。

リストをデフォルトのコレクションとして使用する傾向があります。 2.12.6からデフォルトでは不変のSeqがデフォルトで不変になりました。

44
Rich Oliver

import scala.collection.mutable.MutableList を使用するか、本当に突然変異が必要な場合は同様のものを使用します。

import scala.collection.mutable.MutableList
val x = MutableList(1, 2, 3, 4, 5)
x += 6 // MutableList(1, 2, 3, 4, 5, 6)
x ++= MutableList(7, 8, 9) // MutableList(1, 2, 3, 4, 5, 6, 7, 8, 9)
11
Anthony Accioly

試したすべてのコマンドの結果を説明しようとします。

_scala> val l = 1.0 :: 5.5 :: Nil
l: List[Double] = List(1.0, 5.5)
_

まず、List_scala.collection.immutable.List_ (Predef.scalaで定義)への型エイリアスです。

Listコンパニオンオブジェクトを使用すると、Listをインスタンス化するより簡単な方法になります。例:List(1.0,5.5)

_scala> l
res0: List[Double] = List(1.0, 5.5)

scala> l ::: List(2.2, 3.7)
res1: List[Double] = List(1.0, 5.5, 2.2, 3.7)
_

_:::_は、指定されたリスト接頭辞とこのリストを連結した結果のリストを返します

元のリストは変更されません

_scala> List(l) :+ 2.2
res2: List[Any] = List(List(1.0, 5.5), 2.2)
_

List(l)は_List[List[Double]]_であることは間違いありません。

_:+_は、このリストのすべての要素とそれに続くelemで構成される新しいリストを返します。

タイプは_List[Any]_とDoubleの共通スーパークラスであるため、_List[Double]_です。

_scala> l
res3: List[Double] = List(1.0, 5.5)
_

__は、_immutable.List_のメソッドがリストを変更しなかったため、変更されません。

8
Yann Moisan

既存のリストに要素を追加したいので、var List [Int]を使用して、同じリストに要素を追加し続けることができます。注->次のように、既存のリストに要素を挿入する必要があります。

var l:List [int] = List()//空のリストを作成します

l = 3 :: l //リストの先頭に3を追加します

l = 4 :: l //リストの先頭としてint 4を作成

//ここでlを印刷すると、リストに2つの要素が表示されます(4、3)

1
Aaditya Shukla