【问题标题】:Appending element to list in Scala将元素附加到 Scala 中的列表
【发布时间】:2014-06-10 03:37:37
【问题描述】:
val indices: List[Int] = List()
val featValues: List[Double] = List()
for (f <- feat) {
    val q = f.split(':')
    if (q.length == 2) {
        println(q.mkString("\n")) // works fine, displays info
       indices :+ (q(0).toInt)
       featValues :+ (q(1).toDouble)

}
}
println(indices.mkString("\n") + indices.length) // prints nothing and 0?

indicesfeatValues 未被填充。我在这里不知所措。

【问题讨论】:

  • 当没有Array 为证时,为什么你的问题标题会提到“数组”?
  • 我在两者之间来回走动,认为它类似于 Java,看看这是否能解决问题。只是我的困惑。

标签: scala immutability mutable


【解决方案1】:

您不能将任何内容附加到不可变数据结构中,例如存储在val(不可变命名槽)中的List

您的代码所做的是每次添加一个元素时创建一个新列表,然后将其丢弃(不对其执行任何操作)—列表上的 :+ 方法不会修改列表(甚至当它是一个可变列表时,例如 ArrayBuffer) 但总是返回一个新列表。

为了实现您想要的,最快的方法(相对于正确的方法)是使用var(通常首选):

var xs = List.empty[Int]
xs :+= 123  // same as `xs = xs :+ 123`

或包含可变集合的val

import scala.collection.mutable.ArrayBuffer

val buf = ArrayBuffer.empty[Int]
buf += 123

但是,如果你真的想让你的代码符合习惯,你应该只使用函数式方法:

val indiciesAndFeatVals = feat.map { f =>
    val Array(q0, q1) = f.split(':')  // pattern matching in action
    (q0.toInt, q1.toDouble)
}

这将为您提供一系列对,然后您可以将其unzip 分配给 2 个单独的集合:

val (indicies, featVals) = indiciesAndFeatVals.unzip

这种方法将避免使用任何可变数据结构以及vars(即可变槽)。

【讨论】:

  • 只是想知道,这个呢:stackoverflow.com/questions/7500081/…
  • 你具体指的是什么? Array的使用?
  • 是的,它不是不可变的吗?
  • 你是对的:Array 不是一成不变的;它与 Java 中的旧数组相同;除非出于性能或兼容性原因需要,否则我不会在新编写的 Scala 代码中使用它。在很多情况下,纯函数式/不可变方法不如命令式/可变方法好或更好。通常,您仅在绝对必要时才使用使用可变性的算法,例如一旦您确定了代码中的瓶颈,或者如果它更简单(某些算法可能就是这种情况),就可以进行优化。
猜你喜欢
  • 2017-06-23
  • 2020-09-02
  • 1970-01-01
  • 2013-02-10
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
  • 2022-01-04
  • 2015-02-05
相关资源
最近更新 更多