在 Scala 中,我如何执行 SQL SUM 和 GROUP BY 的等效操作? [英] In Scala, how can I do the equivalent of an SQL SUM and GROUP BY?
问题描述
例如,假设我有
val list: List[(String, Double)]
有值
"04-03-1985", 1.5
"05-03-1985", 2.4
"05-03-1985", 1.3
我如何生成一个新列表
"04-03-1985", 1.5
"05-03-1985", 3.7
推荐答案
这里是单行的.除非真正内化这些高阶函数的类型,否则它不是特别易读.
Here's a one-liner. It's not particularly readable, unless one really internalizes the types of these higher order functions.
val s = Seq(("04-03-1985" -> 1.5),
("05-03-1985" -> 2.4),
("05-03-1985" -> 1.3))
s.groupBy(_._1).mapValues(_.map(_._2).sum)
// returns: Map(04-03-1985 -> 1.5, 05-03-1985 -> 3.7)
另一种方法是使用 fold 逐个添加键值对,
Another approach is to add the key-value pairs one-by-one using fold,
s.foldLeft(Map[String, Double]()) { case (m, (k, v)) =>
m + (k -> (v + m.getOrElse(k, 0d)))
}
在我看来,理解的等价物是最容易获得的,
The equivalent for comprehension is most accessible, in my opinion,
var m = Map[String, Double]()
for ((k, v) <- s) {
m += k -> (v + m.getOrElse(k, 0d))
}
也许使用 Scalaz 的用于 Map 的 monoid 类型类可以做一些更好的事情.
Maybe something nicer can be done with Scalaz's monoid typeclass for Map.
请注意,您可以使用 toSeq
和 Map[K, V]
和 Seq[(K, V)]
之间的转换code>toMap 方法.
Note that you can convert between Map[K, V]
and Seq[(K, V)]
using the toSeq
and toMap
methods.
更新.经过更多的思考,我认为自然抽象将是一个multimap"类型的转换,
Update. After pondering it some more, I think the natural abstraction would be a "multimap" conversion, of type,
def seqToMultimap[A, B](s: Seq[(A, B)]): Map[A, Seq[B]]
通过个人图书馆中适当的隐式扩展,您可以这样写:
With the appropriate implicit extension in one's personal library, one could then write:
s.toMultimap.mapValues(_.sum)
在我看来,这是最清楚的!
This is the clearest of all, in my opinion!
这篇关于在 Scala 中,我如何执行 SQL SUM 和 GROUP BY 的等效操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!