【问题标题】:Add element to a list In Scala在Scala中将元素添加到列表中
【发布时间】:2013-11-05 18:44:00
【问题描述】:

我正在运行 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 和 3.7)甜蜜!我什至检查了别人的代码以寻求帮助:Appending an element to the end of a list in Scala 使用新的构造 :+。所以在这个阶段我很高兴,但我打电话给l,我得到了意想不到的结果:`res3: List[Double] = List(1.0, 5.5)'。

我添加的元素在哪里?以及如何正确添加这些元素,以便当我调用 l 时,我会得到一个包含我添加的所有内容的新列表?

【问题讨论】:

  • 您的所有语句实际上都没有修改l
  • 列表通常是不可变的。在后一种情况下,您正在创建一个新列表,而原始列表保持不变。您可以使用可变列表或使用一种方法来重新附加。在 REPL 中,您也可以执行以下操作:val 转换 = List(l) :+ 2.2,然后打印出新值。

标签: list scala


【解决方案1】:

您正在使用不可变列表。对 List 的操作返回一个新的 List。旧列表保持不变。如果另一个类/方法持有对原始集合的引用并且依赖它保持不变,这将非常有用。您可以使用不同的命名 val,如

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

或使用 var

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))

但是,您应该只在性能关键代码中使用可变集合。不可变集合更容易推理和使用。一大优势是不可变列表和scala.collection.immutable.Vector 是协变的。如果这对您还没有任何意义,请不要担心。它的优点是您可以在不完全理解它的情况下使用它。因此,您默认使用的集合实际上是 scala.collection.immutable.List,它只是自动为您导入的。

我倾向于使用 List 作为我的默认集合。从 2.12.6 Seq 默认为不可变 Seq 在此之前它默认为不可变。

【讨论】:

    【解决方案2】:

    如果您确实需要突变,请使用 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)
    

    【讨论】:

      【解决方案3】:

      我将尝试解释您尝试的所有命令的结果。

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

      首先,Listscala.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],因为它是List[Double]Double之间的公共超类

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

      l 未修改,因为immutable.List 上的任何方法都没有修改列表。

      【讨论】:

        【解决方案4】:

        由于您想将元素附加到现有列表中,您可以使用 var List[Int] 然后继续将元素添加到同一个列表中。 注意 -> 您必须确保将元素插入到现有列表中,如下所示:-

        var l: List[int] = List() // 创建一个空列表

        l = 3 :: l // 将 3 添加到列表的头部

        l = 4 :: l // 将 int 4 作为列表的头部

        // 现在当你打印 l 时,你会在列表中看到两个元素 (4, 3)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-09-02
          • 2014-06-10
          • 2017-06-23
          • 2014-12-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多