简体   繁体   English

在Scala中将元素添加到不可变列表

[英]Adding elements to an immutable list in Scala

In Scala the way you add elements to an immutable list as follows: 在Scala中,将元素添加到不可变列表的方式如下:

    val l = 1 :: 2 :: Nil
    l: List[Int] = List(1, 2)

What this means is you first create a Nil (Empty) List, and to that you add 2 and then 1. ie These operations are right-associated. 这意味着您首先创建一个Nil(空)列表,然后向其添加2,然后添加1。即,这些操作是右相关的。 So, effectively, it can be re-written in a clearer way, like so: 因此,实际上,可以用更清晰的方式重写它,如下所示:

    val l = (1 :: (2 :: Nil))
    l: List[Int] = List(1, 2)

The question is, if List is supposed to preserve the order of insertion, and if 2 is added first to an empty list and then 1 is added, then why is the answer not l: List[Int] = List(2, 1) ?? 问题是,如果List应该保留插入顺序,并且如果先将2添加到一个空列表中,然后再添加1,那么答案为何不是l: List[Int] = List(2, 1) ??

It's just convention. 这只是约定。 Lists are basically stacks. 列表基本上是堆栈。 It's most efficient to access or modify the most-recently added items. 访问或修改最近添加的项目是最有效的。 You could just as well consider the head of the list to be the final item ordinally, in which case, your suggested notation would be appropriate. 通常,您也可以将列表的开头视为最后一项,在这种情况下,建议的符号将是适当的。

I would speculate that the reason for the convention is that we don't typically put much care into how a list was constructed, but we do often want to consider the first item accessed to be the initial item in the ordering, and so the notation reflects that. 我推测,采用该约定的原因是,我们通常不十分注重列表的构造方式,但我们确实经常希望将访问的第一个项目视为排序中的初始项目,因此将其表示为反映出这一点。

This is because elements are prepended: first 2 then 1 . 这是因为元素是前置的:先21

From definition of cons method: 从缺点方法的定义:

  def ::[B >: A] (x: B): List[B] =
    new scala.collection.immutable.::(x, this)

here you can see that each time new instance of case class scala.collection.immutable.:: is created: 在这里您可以看到,每次创建案例类scala.collection.immutable.::新实例时:

case class ::[B](val head: B, var tail: List[B]) extends List[B]

you just use your new element as a head for new list and your whole previous list as its tail . 你只需要使用你的新元素作为head为新的列表和你的整个前面的列表作为它的tail

Also prepend operation for immutable List takes constant time O(1), append is linear O(n) (from Scala docs ). 不可变List prepend操作也需要固定时间O(1),append是线性O(n)(来自Scala docs )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM