当需要积累一些数据时,这是很常见的。我习惯这样做的方法是将数据块附加到数组。但这对scala来说是一种不好的做法,所以我该如何避免它呢?
答案 0 :(得分:4)
嗯,有两种处理累积的通用方法:递归和折叠。让我们看看每个的非常简单的例子,来计算列表值的总和。
def sumRecursively(list: List[Int]): Int = {
def recurse(list: List[Int], acc: Int): Int =
if (list.isEmpty) acc
else recurse(list.tail, acc + list.head)
recurse(list, 0)
}
def sumFolding(list: List[Int]): Int =
list.foldLeft(0){ case (acc, n) => acc + n }
这方面有很多变化,可以更好地处理这种情况。
答案 1 :(得分:2)
实际上,事实并非如此。您可以在scala中使用Vector
,默认情况下,它是scala.collection.immutable
包的一部分。这将创建一个不可变集合,每次附加它时都会返回一个新的(不同的)实例。
更多信息:
http://www.scala-lang.org/docu/files/collections-api/collections_15.html
答案 2 :(得分:2)
对于大多数常见用途,“map”和“flatMap”操作用于在功能上生成数据结构。两者都以一个数据结构开始,对其中的每个元素应用一些操作,并返回与原始元素形状相同的新数据结构。它们在如何填充新数据结构方面有所不同。这两个是如此常见和如此强大,以至于Scala包含一个特殊的语法,即for-comprehension,以支持它们。 for-comprehension看起来表面上类似于Java风格的for循环,但实际上编译为一系列map和flatMap调用(在其他一些调用中)。
在函数式编程中,通常会将问题从一个数据结构分解为另一个数据结构,而不是明确地描述构建和销毁数据结构所需的步骤。这需要一些人习惯,特别是在弄清楚要启动什么数据结构时。一旦掌握了它,这是一项非常强大的技术,可以清晰,准确地表达大块功能,并且几乎没有空间容纳蠕虫。
值得注意的是,“map”和“flatMap”实际上是另一个更强大的功能的特殊情况:“fold”。 “fold”(由于技术原因同时实现为“foldLeft”和“foldRight”)可用于构建数据结构并将其分解。