11

我目前正在尝试 Scala 中的东西,试图习惯函数式编程以及再次学习一门新语言(自上次以来已经有一段时间了)。

现在给出一个字符串列表,如果我想将它们合并成一个长字符串(例如"scala", "is", "fun" => "scalaisfun"),我想一种方法是foldRight对各个元素执行 a 并应用连接。另一种方法,公认要简单得多,是调用mkString.

我在 github 上查了一下,但找不到相应函数的源代码(任何帮助将不胜感激),所以我不确定这些函数是如何实现的。从我的脑海中,我认为mkString它更灵活,但感觉可能foldRight在某个地方的实现中存在。这有什么道理吗?

否则,scaladocs 提到mkString调用toString每个相应的元素。看到它们一开始就已经是字符串,mkString在这种特殊情况下,这可能是一个负面因素。关于两种方法的优缺点,在性能、简单/优雅等方面有什么评论吗?

4

3 回答 3

23

简单的答案:使用mkString.

someString.toString 返回相同的对象。

mkString用单个实现StringBuilder,它只创建 1 个新字符串。与foldLeft您一起创建N-1新的字符串。

您可以使用StringBuilderin foldLeft,它将与 一样快mkString,但mkString更短:

strings.foldLeft(new StringBuilder){ (sb, s) => sb append s }.toString
strings.mkString // same result, at least the same speed
于 2013-05-08T18:39:42.477 回答
6

除非你真的需要它,否则不要使用foldRight它,因为它会溢出你的大型集合(对于某些类型的集合)的堆栈。 foldLeftorfold会工作(不在堆栈上存储中间数据),但会比mkString. 如果列表是非空的,reducereduceLeft将起作用。

于 2013-05-08T18:50:24.747 回答
3

我记得服务,mkString使用 StringBuilder 来构建高效的字符串。你可以使用 ScalaStringBuilder作为累加器来完成同样的事情,但是如果已经可以为你做所有这些好事,那foldRight又何必费心呢。mkStringPlusmkString还为您提供了额外的好处,包括可选的分隔符。你可以这样做,foldRight但它已经为你完成了mkString

于 2013-05-08T18:38:32.250 回答