该解决方案已经给出的,但我认为这是一个需要更多的解释:
你只能离开括号和点,如果你的表现是在运营商的地位。如果表达式的格式为<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