将元素追加到Scala中列表的末尾

Mas*_*iar 210 arrays scala

这听起来像个愚蠢的问题,但我在互联网上找到的只是垃圾.我根本无法将类型的元素添加T到列表中List[T].我试过myList ::= myElement但似乎它创建了一个奇怪的对象并且访问myList.last总是返回放在列表中的第一个元素.

Lan*_*dei 372

List(1,2,3) :+ 4

Results in List[Int] = List(1, 2, 3, 4)
Run Code Online (Sandbox Code Playgroud)

注意,该操作具有O(n)的复杂度.如果您经常需要此操作,或者对于长列表,请考虑使用其他数据类型(例如ListBuffer).

  • @pisaruk如果是这样的话,可以保持指向头部和尾部的指针.但是,[scala中的列表](http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List)是不可变的,这意味着"修改"最后一个元素列表需要首先复制它.它的副本是O(n) - 而不是列表本身的遍历. (36认同)
  • 对于渐近复杂性,没有O(2*n),常数因子被忽略.我认为`List`被转换为`ListBuffer`,元素被追加,`ListBuffer`被转换回来(非常像Java中的`String`和`StringBuilder`),但这只是猜测. (6认同)
  • cons运算符具有复杂度O(1),因为它在列表的"预期"侧工作. (3认同)
  • 它是O(n)因为你必须完全遍历列表才能到达最后一个元素指针并且能够追加使最后一个元素指针指向它的元素. (2认同)
  • 我认为这是O(n)只是因为创建了一个全新的列表 (2认同)
  • @ aaa90210你在拖钓吗?当然你不能修改一个不可变的列表,呃...... (2认同)

agi*_*eel 65

那是因为你不应该这样做(至少有一个不可变的列表).如果你真的需要在数据结构的末尾添加一个元素,并且这个数据结构确实需要是一个列表,而且这个列表确实必须是不可变的,那么请执行以下操作:

(4 :: List(1,2,3).reverse).reverse
Run Code Online (Sandbox Code Playgroud)

或者那个:

List(1,2,3) ::: List(4)
Run Code Online (Sandbox Code Playgroud)

  • 如果要添加许多元素,那么"通过前置然后反转它来构建列表"是一个有用的模式,但我不认为应用它是一个好主意,就像在向单个元素添加单个元素时一样.现有清单."双反向"技巧重建列表两次,而`:+`,效率低,只重建一次. (28认同)
  • @Masiar如果你想要不变性和高效追加,可以使用Vector.请参阅http://www.scala-lang.org/docu/files/collections-api/collections.html中的性能特征部分 (6认同)

Mar*_*ger 24

Scala中的列表不是为了修改而设计的.实际上,您无法向Scala添加元素List; 它是一个不可变的数据结构,就像Java String一样.在Scala中"向列表中添加元素"时实际执行的操作是从现有列表创建新列表.(资源)

我建议使用a ArrayBuffer或a 来代替使用这些用例的列表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)
Run Code Online (Sandbox Code Playgroud)


Ven*_*kat 5

这类似于其中一个答案,但方式不同:

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)
Run Code Online (Sandbox Code Playgroud)