2017-02-03 25 views
3

在我正在进行的一个项目中,我经常发现自己在做下面的模式。斯卡拉groupBy + mapValues +映射回初始格式。有没有更好的方法

给定一个案例类别X(a:A,b:B,c:C,d:Int),以及这样的X的列表x:列表[X], 我想做数据库等价的分组由a,b,c组成,同时用d进行求和,返回类型为List [X]。

我通常最终做的是

xs.groupBy{case X(a,b,c,d) => (a,b,c)).mapValues(_.sum).map(((a,b,c),d)) => X(a,b,c,d)) 

我的问题,是有没有更好/更清晰/更地道与任一阶标准库或Scalaz(这样做的方式。如果d是任意类型的也许是Monoid实例)?

+0

你可以发布示例列表和示例输出吗?我不确定你想在这里做什么? –

+0

稍后会做一下 –

+0

你可能想看看这个scalaz的例子:http://stackoverflow.com/questions/7142514/in-scala-how-can-i-do-the-equivalent-of-an-sql -sum-and-group-by#answer-7168846 –

回答

0

我想我知道你在努力实现什么,我发现了一个更短的方法来实现这一点,你不必使用mapValues,然后映射,而是可以用一张地图做所有事情,就像这样:

case class X(a: String, b: String, c: String, d: Int){ 
    def +(that: X) = X(a,b,c, d+that.d) 
} 

val list = List(X("1","2","3",4),X("1","2","3",5),X("11","22","33",6),X("11","22","33",9)) 

list.groupBy{ 
    case X(a,b,c,d) => (a,b,c)}.map{ case (k,v) => X(k._1, k._2, k._3, v.reduce(_ + _).d)} 

如果你可以用和与你的类将是更短,更清洁,但减少或者是没有那么糟糕。