該解決方案已經給出的,但我認爲這是一個需要更多的解釋:
你只能離開括號和點,如果你的表現是在運營商的地位。如果表達式的格式爲<object> <method> <param>
,則表達式在運算符位置。對於包含多個顯式參數列表的方法,情況並非如此foldLeft
。因此你必須寫<list>.foldLeft(<init>)(<function>)
。儘管如此,斯卡拉有一個特殊的規則來解決這個問題 - 你可以插入另一組圓括號:(<list> foldLeft <init>) (<function>)
。此外還有另一種稱爲/:
的方法,它是foldLeft
的同義詞,定義爲def /:[B](z: B)(op: (B, A) => B): B = foldLeft(z)(op)
。它允許你寫(<init> /: <list>) (<function>)
。也許你剛纔注意到第一個圓括號之間的符號被交換 - 這是因爲每個方法以冒號結尾的規則是正確的 - 而不是左結合(further explanation)。
現在我想給你作進一步的重構一些提示:
Tuple2[A, B]
可以寫成(A, B)
- 你不必編寫所有類型。他們中的一些人可以 - 也應該 - 留下來清理你的代碼(我知道你是一個初學者,並且想寫這個,只是作爲一個提示...)。但不要離開
- 列表大多被命名爲
xs
或ys
,因爲這意味着「很多x」或「很多y」。這不是很重要,但共同點
- 您可以在參數上進行匹配以提取它們以易於讀取名稱:
... { case (a, (b,c)) => ...}
- 您的代碼不起作用,因爲它聲稱該任務。您需要類似
List.fill(<n>)(<elem>)
- 不要將元素添加到列表中,這是
O(n)
。隱含地是:::
是附加操作 - 請看sources。
- 對於這項任務
foldLeft
不是最好的解決方案。 foldRight
或同義詞:\
可能更高效,因爲:::
操作需要較少的元素進行復制。但我更喜歡flatMap
(見下文),這是一個map+flatten
- 您可以使用一個換理解,以解決這個問題,這往往會容易閱讀。有關更多信息,請參閱this內部如何實現理解。
總而言之例如解決方案:
object Test extends App {
def decode1(l: List[Tuple2[Int, Symbol]]): List[Symbol] =
l.foldLeft(List[Symbol]()) { (symbols: List[Symbol], e: Tuple2[Int, Symbol]) => symbols ::: List.fill(e._1)(e._2) }
def decode2(xs: List[(Int, Symbol)]): List[Symbol] =
(xs foldLeft List.empty[Symbol]) { case (xs, (n, s)) => xs ::: List.fill(n)(s) }
def decode3(xs: List[(Int, Symbol)]): List[Symbol] =
(xs foldRight List.empty[Symbol]) { case ((n, s), xs) => List.fill(n)(s) ::: xs }
def decode4(xs: List[(Int, Symbol)]): List[Symbol] =
(List.empty[Symbol] /: xs) { case (xs, (n, s)) => xs ::: List.fill(n)(s) }
def decode5(xs: List[(Int, Symbol)]): List[Symbol] =
xs flatMap { case (n, s) => List.fill(n)(s) }
def decode6(xs: List[(Int, Symbol)]): List[Symbol] =
for {
(n, s) <- xs
ys <- List.fill(n)(s)
} yield ys
val xs = List((4, 'a), (1, 'b), (2, 'c), (2, 'a), (1, 'd), (4, 'e))
val ys = List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e)
println("start testing")
val tests = List[List[(Int, Symbol)] => List[Symbol]](decode1, decode2, decode3, decode4, decode5, decode6)
for (t <- tests)
assert(t(xs) == ys)
println("finished")
}
感謝肖恩的answer.Are那裏有沒有什麼好的文檔,鏈接,博客文章等這件事嗎? – 2012-07-16 18:29:09
這裏有一些條目已經圍繞一些: http://stackoverflow.com/questions/5592642/when-to-use-parenthesis-in-scala-infix-notation 我會說一條經驗法則只有在有明確的理由時才能做到(如「4 + 4」情況)。 – 2012-07-16 18:31:54
庫爾。再次感謝肖恩。 – 2012-07-16 18:34:25