2013-05-08 15 views
10

我目前正在嘗試Scala中的事情,嘗試習慣函數式編程以及再次傾斜一種新語言(這是自上次以來的一段時間)。使用mkString合併字符串列表vs foldRight

現在給出一個字符串列表,如果我想將它們合併成一個長字符串(例如"scala", "is", "fun" => "scalaisfun"),我想一個辦法是做一個foldRight並在各個元素上應用連接。無可否認,更簡單的另一種方法是致電mkString

我檢查了github,但無法真正找到各自功能的源代碼(任何幫助,將不勝感激),所以我不知道如何實現功能。從我的頭頂來看,我認爲mkString更靈活,但感覺在某處可能有foldRight。它有什麼道理嗎?

否則,scaladocs會提及mkString針對每個相應元素的toString調用。看到它們已經是字符串,在這種情況下,這可能是mkString的一個負面因素。對性能,簡單/優雅等兩種方法的優缺點有何評論?

+0

這裏是mkString的來源,如果你有興趣。 https://www.assembla.com/code/scala-eclipse-toolchain/git/nodes/src/library/scala/collection/TraversableOnce.scala?rev=9752caefeb97123f195b32b4166577e59bf22bce#ln262 – sberry 2013-05-08 18:35:08

回答

17

簡單的答案:使用mkString

someString.toStringreturns相同的對象。

mkString使用單個StringBuilder實現,它只創建1個新字符串。用foldLeft您將創建N-1新字符串。

你可以在foldLeft使用StringBuilder,它會以最快的速度mkString,但mkString較短:

strings.foldLeft(new StringBuilder){ (sb, s) => sb append s }.toString 
strings.mkString // same result, at least the same speed 
+1

在你的例子中,相同的速度並不完全正確foldLeft,使用StringBuilder的不正確的初始容量,最終可能創建依賴於輸入多個字符串,不知道第一mkstring迭代,以確定正確的StringBuilder的容量,但如果是這樣的話,那麼他們是不一樣的速度,否則再有就是不保證這兩者都只會創建一個新字符串。 – 2015-05-27 19:54:02

2

Im內存服務,mkString使用StringBuilder來構建高效的字符串。你可以使用斯卡拉StringBuilder作爲累加器來完成同樣的事情,但爲什麼如果mkString已經可以爲你做所有這些好東西了。 Plus mkString爲您提供了還包括可選分隔符的額外好處。你可以在foldRight中做到這一點,但它已經完成了與mkString

5

不要使用foldRight,除非你真的需要它,因爲它會溢出你的籌碼爲大集合(對於某些類型的集合)。 foldLeftfold可以工作(不會在堆棧中存儲中間數據),但會比mkString更慢且更笨拙。如果列表不爲空,則reducereduceLeft也將起作用。