我使用的是 scala 2.12。
我有一个案例类如下:
case class MyClass(date: java.util.Date, book: String, priceLocal: Double, priceConv: Double)
我能够根据日期和预订进行分组。
例如,对于:
val listOfMyClass = List(
MyClass(20190708, "book1", 100, 120),
MyClass(20190708, "book1", 200, 220),
MyClass(20190708, "book2", 50, 60),
MyClass(20190708, "book2", 60, 70)
)
val groupedData = listOfMyClass.groupBy(t => (t.date, t.book))
我想要像 SQL 中那样的数据:
(20190708, "book1", 300, 340)
(20190708, "book2", 110, 130)
我能够映射并求和一列,但无法使用这两列。
val groupedDataSum = listOfMyClass.groupBy(t => (t.date, t.book)).mapValues(_.map(_.priceLocal).sum)
但是如何将第二列也用作总和?
最佳答案
您可以混合使用 groupBy
(按日期和书籍对元素进行分组)和 reduce
来累积分组值:
// val list = List(
// MyClass(Date(2019, 7, 8), "book1", 100, 120),
// MyClass(Date(2019, 7, 8), "book1", 200, 220),
// MyClass(Date(2019, 7, 8), "book2", 50, 60),
// MyClass(Date(2019, 7, 8), "book2", 60, 70)
// )
list
.groupBy { case MyClass(date, book, _, _) => (date, book) }
.mapValues { values =>
values
.map { case MyClass(_, _, priceLocal, priceConv) => (priceLocal, priceConv) }
.reduce((x, y) => (x._1 + y._1, x._2 + y._2))
}
.map { case ((date, book), (priceLocal, priceConv)) =>
(date, book, priceLocal, priceConv)
}
// List(
// (Date(2019, 7, 8), "book1", 300, 340),
// (Date(2019, 7, 8), "book2", 110, 130)
// )
这个:
按日期和书籍对字符进行分组 (
groupBy
)通过以下方式映射每个分组值 (
mapValues
):- 将值映射为价格元组
- 并通过逐个求和来减少这些元组
将元组(日期、书籍)映射到元组(价格、价格)到 4 个元素的元组
关于scala - GroupBy 多列作为键并对多列求和,如 sql 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56941818/