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


223

馬鹿げた質問のように聞こえますが、インターネットで見つけたのはゴミです。タイプの要素をTリストに追加できませんList[T]。私は試しましたmyList ::= myElementが、それは奇妙なオブジェクトを作成しmyList.last、リストに入れられた最初の要素を常に返すためにアクセスするようです。

回答:


394
List(1,2,3) :+ 4

Results in List[Int] = List(1, 2, 3, 4)

この操作はO(n)の複雑さを持つことに注意してください。この操作が頻繁に必要な場合、または長いリストの場合は、別のデータ型(ListBufferなど)の使用を検討してください。


7
O(2 * n)はなく、漸近的な複雑さのために定数係数は無視されます。私が考えるListに変換されListBuffer、要素が追加され、ListBuffer変換されたバック(ほとんどのようにStringしてStringBuilderJavaで)、それはただの推測です。
Landei 2013

2
最後の要素ポインターに到達し、最後の要素ポインターがそれを指すように要素を追加できるようにするには、リスト全体を走査する必要があるため、O(n)になります。
pisaruk 2013

39
@pisarukの場合、頭と尾へのポインタを維持するだけで済みます。ただし、scalaリストは不変です。つまり、リストの最後の要素を「変更」するには、最初にそのコピーを作成する必要があります。そのコピーはO(n)です-リスト自体の走査ではありません。

2
まったく新しいリストを作成したからといって、O(n)だと思います
Raffaele Rossi

3
cons演算子は、リストの「意図した」側で機能するため、複雑度O(1)です。
Landei、2015

67

それは、(少なくとも不変のリストでは)やるべきではないからです。本当にデータ構造の最後に要素を追加する必要があり、このデータ構造が本当にリストである必要があり、このリストが本当に不変である必要がある場合は、次のいずれかを実行します。

(4 :: List(1,2,3).reverse).reverse

またはその:

List(1,2,3) ::: List(4)

どうもありがとう!それがまさに私が探していたものです。私はあなたの答えからそれをするべきではないと思いますが...私は私の構造を修正して何ができるか見ていきます。再度、感謝します。
Masiar 2011年

6
不変性と効率的な追加が必要な場合、@ Masiarはベクターを使用します。scala-lang.org/docu/files/collections-api/collections.htmlの
Arjan Blokzijl

29
追加する要素が多い場合は、「先頭に追加してリストを作成してから逆にする」パターンが便利ですが、単一の要素を既存のリスト。「二重逆」のトリックは、リストを2回再構築しますが:+、効率が悪い場合は、1回しか再構築しません。
Nicolas Payette、2011年

25

Scalaのリストは変更するようには設計されていません。実際、要素をScalaに追加することはできませんList。これは、Java文字列のような不変のデータ構造です。Scalaで「リストに要素を追加する」ときに実際に行うことは、既存のリストから新しいリストを作成することです。(ソース)

そのようなユースケースにリストを使用する代わりに、ArrayBufferまたはを使用することをお勧めしますListBuffer。これらのデータ構造は、新しい要素が追加されるように設計されています。

最後に、すべての操作が完了したら、バッファをリストに変換できます。次のREPLの例を参照してください。

scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer

scala> var fruits = new ListBuffer[String]()
fruits: scala.collection.mutable.ListBuffer[String] = ListBuffer()

scala> fruits += "Apple"
res0: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple)

scala> fruits += "Banana"
res1: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple, Banana)

scala> fruits += "Orange"
res2: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple, Banana, Orange)

scala> val fruitsList = fruits.toList
fruitsList: List[String] = List(Apple, Banana, Orange)

3

これは回答の1つに似ていますが、方法が異なります。

scala> val x=List(1,2,3)
x: List[Int] = List(1, 2, 3)

scala> val y=x:::4::Nil
y: List[Int] = List(1, 2, 3, 4)

2

2つのリストまたはlist&array Appendを追加または追加できます

var l = List(1,2,3)    
l=l:+4 
Result : 1 2 3 4  
var ar = Array(4,5,6)    
for(x<-ar)    
{ l=l:+x}  
  l.foreach(println)

Result:1 2 3 4 5 6

追加:

var l = List[Int]()  
   for(x<-ar)  
    { l=x::l } //prepending    
     l.foreach(println)   

Result:6 5 4 1 2 3

1
はい、できますが、他の回答で述べられているすべての理由から、それは悪い考えです。
jwvh 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.