Scala中对Map使用foldLeft函数

40

你如何使用Map.foldLeft?根据文档,它看起来像是

foldLeft [B] (z: B)(op: (B, (A, B)) ⇒ B) : B

但是我遇到了困难:

Map("first"->1,"second"->2).foldLeft(0)((a,(k,v)) => a+v )

出错指的是k前面的开括号。

4个回答

93

如果你想使用(a, (k, v))的语法,你需要告诉编译器使用模式匹配。

Map("first"->1, "second"->2).foldLeft(0){ case (a, (k, v)) => a+v }

请注意,case语句需要使用花括号。


2
为什么需要模式匹配?在foldLeft中还有其他可以匹配的模式吗? - ron_ron

19

我认为,你无法像你期望的那样在元组上进行模式匹配:

Map("first"->1,"second"->2).foldLeft(0)((a, t) => a + t._2)

实际上,使用值和求和更简单。

Map("first"->1,"second"->2).values.sum

6
他可以对元组进行模式匹配。不过,要进行模式匹配,就需要使用case语句。 - Daniel C. Sobral
@Daniel 这就是我像律师一样的句子的优点:它是正确的(他无法按照他预期的方式进行模式匹配),但我忘记了案例语法。 - Thomas Jung
1
对于像这样的问题,使用valuesmapValues绝对是最清晰的解决方案(这几乎总是正确选择)。 - Kevin Wright

8

关键是使用部分函数作为代码块,换句话说,您需要添加一个匹配参数的 case 语句:

Map("first" -> 1, "second" -> 2).foldLeft(0) { case (a, (k, v)) => a + v }

非常感谢你,Theo!这正是我一直在寻找的东西...但是case如何在没有match关键字的情况下使用,它又是如何作为解构操作使用的? - NikolaS

5

这并不是对你的问题的真正回答,但当我开始使用fold时,我发现它很有用,所以还是说一下吧!注意, /: 方法是 foldLeft 的“别名”,因为有两个原因可以更清晰:

xs.foldLeft(y) { (yy, x) => /* ... */ }

(y /: xs) { (yy, x) => /* ... */ }

请注意第二行:
  • 更清晰的是值y被折叠到集合xs
  • 你可以轻松记住Tuple2参数的顺序与"call"方法的顺序相同

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接