scala - Scala:如何对 Map[String, List[(String, Map[Long, Int])]] 中的 mapValues 求和
问题描述
这是一个复杂的结构,例如:
val testMap: Map[String, List[(String, Map[Long, Int])]] = Map(
"test1" ->
List(
("test1", Map(1111111111L -> 2)),
("test1", Map(1111111111L -> 2)),
("test1", Map(1111111111L -> 2)),
("test1", Map(1111111111L -> 2)),
("test1", Map(2222222222L -> 2))
)
)
如何用相同的键对值求和?我期望结果是:
Map(test1 -> Map(1111111111 -> 8, 2222222222 -> 2))
到目前为止我尝试过的是:
val res = testMap.mapValues(_.map(_._2).reduce(_ ++ _))
但我得到的结果是:
Map(test1 -> Map(1111111111 -> 2, 2222222222 -> 2))
1111111111 的值为 2 而不是 8。我该如何解决这个问题?谢谢!
解决方案
如果您需要减少内部映射中的值,您可以使用 foldLeft 并累积结果映射:
def combineInner(mapA: Map[Long, Int], mapB: Map[Long, Int]): Map[Long, Int] = {
mapA.foldLeft(mapB) {
case (mapWithSum, (key, value)) =>
mapWithSum.updated(key, mapWithSum.getOrElse(key, 0) + value)
}
}
val res = testMap.mapValues(_.map(_._2).reduce(combineInner))
但请记住,您将以这种方式丢失外部映射键和列表中的字符串值(对列表中的口渴元素)。
更新:如果你可以使用猫库,你可以做更简单的只使用猫半组类型类:
import cats.implicits._
val res = testMap.mapValues(_.map(_._2).reduce(_ |+| _))
推荐阅读
- arrays - 尝试区分“...”时出错。只允许使用数组和可迭代对象。(使用 switchMap)
- csv - Hive 可以处理 CSV 文件中的多个双引号吗?
- html - 如何将sql查询结果转换为带有属性的html标签
- logging - openAM 认证日志
- https - NodeMCU 强制门户网站服务器响应 HTTP,但不响应 HTTPS
- javascript - 当鼠标具有特定类时更改 div 的背景图像
- ios - 目前如何在 Swift 中进行观察?
- abap - 如何提取被调用程序 RAZUGA01 的输出
- arrays - 在 Swift 4.2 中解析 JSON 数据时出现 typeMismatch 错误
- asp.net-core - 如何在 IIS 上运行的 ASP.Net Core MVC 中使用共享库