使用fold来汇总对象属性列表

时间:2014-08-12 22:00:31

标签: scala fold

在此代码中,我尝试将每个值加倍,然后求和v:

case class s(v : Int)
  val l = List(s(2) , s(3))                      
  l.fold(0) ((_.v * 2) + (_.v * 2))

但我收到错误:

  value v is not a member of Any

如何对List中对象的每个属性执行操作?

3 个答案:

答案 0 :(得分:4)

正如其他作者所指出的那样,fold期望你班级的超类型的累加器。类本身也是自己的超类型,所以我们可以编写

case class s(v : Int)
val l = List(s(2) , s(3))                      
l.fold(s(0)){case (acc, elem) => s((acc.v * 2) + (elem.v * 2))}.v

但确实感觉太重了。在这种情况下简单:

l.map(_.v*2).sum

会做得更好。

答案 1 :(得分:2)

fold中的第一个元素是起始元素,你调用0.v,同时注意折叠签名是def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1,这意味着它返回一个超类型的变量对于传递的类型参数,使用foldLeft代替,它允许您构建一个子类型的值:

l.foldLeft(0) ((acc, curr) => acc + (curr.v * 2))

我使用acccurr来更好地查看内部发生的情况,这是缩写形式:

l.foldLeft(0) (_ + _.v * 2)

答案 2 :(得分:1)

由于fold的累加器类型为Int,而不属于s,因此无法执行您想要的操作。对_.v * 2执行Int没有意义。

您可以执行foldLeft(或foldRight):

l.foldLeft(0)(_ + _.v * 2)

或者更简单,使用mapsum

l.map(_.v * 2).sum