在更多"功能性"中进行编程的新功能样式。通常我会写一系列嵌套的foreach循环和+=
到总数。
我的数据结构如下:
Map(
"team1" ->
Map(
"2015" -> Map("wins" -> 30, "losses" -> 5),
"2016" -> Map("wins" -> 3, "losses" -> 7)
),
"team2" ->
Map(
"2015" -> Map("wins" -> 22, "losses" -> 1),
"2016" -> Map("wins" -> 17, "losses" -> 4)
)
)
我想要的是一种数据结构,它简单地抛弃年份信息并由团队一起增加赢/输。
Map(
"team1" -> Map("wins" -> 33, "losses" -> 12),
"team2" -> Map("wins" -> 39, "losses" -> 5)
)
我一直在关注groupBy,但如果我没有这种嵌套结构,这似乎才有用。
有什么想法吗?或者更传统的势在必行/ foreach方法在这里是有利的。
答案 0 :(得分:3)
myMap.map(i => i._1 -> i._2.values.flatMap(_.toList).groupBy(_._1).map(i => i._1 -> i._2.map(_._2).sum))
- 获取所有值
flatMap
列出groupBy
按键- 获取所有分组值并求和
醇>
答案 1 :(得分:2)
定义一个自定义方法,按键添加两个地图:
def addMap(x: Map[String, Int], y: Map[String, Int]) =
x ++ y.map{ case (k, v) => (k, v + x.getOrElse(k, 0))}
m.mapValues(_.values.reduce(addMap(_, _)))
// res16: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,Int]] =
// Map(team1 -> Map(wins -> 33, losses -> 12), team2 -> Map(wins -> 39, losses -> 5))
答案 2 :(得分:1)
使用cats即可:
#
import cats.implicits._
// or
// import cats.instances.map._
// import cats.instances.int._
// import cats.syntax.foldable._
teams.mapValues(_.combineAll)
// Map(
// team1 -> Map(wins -> 33, losses -> 12),
// team2 -> Map(wins -> 39, losses -> 5)
// )
使用combineAll
实例(也由Cats库提供,请参阅Monoid
documentation)结合每年的赢/输地图,其中Monoid[Map[String, Int]]
s的总和对于每一把钥匙。
答案 3 :(得分:1)
.mapValues { _.toSeq
.flatMap(_._2.toSeq)
.groupBy(_._1)
.mapValues(_.foldLeft(0)(_ + _._2)) }
答案 4 :(得分:0)
scala> val sourceMap = Map(
| "team1" ->
| Map(
| "2015" -> Map("wins" -> 30, "losses" -> 5),
| "2016" -> Map("wins" -> 3, "losses" -> 7)
| ),
| "team2" ->
| Map(
| "2015" -> Map("wins" -> 22, "losses" -> 1),
| "2016" -> Map("wins" -> 17, "losses" -> 4)
| )
| )
sourceMap: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,Int]]] = Map(team1 -> Map(2015 -> Map(wins -> 30, losses -> 5), 2016 -> Map(wins -> 3, losses -> 7)), team2 -> Map(2015 -> Map(wins -> 22, losses -> 1), 2016 -> Map(wins -> 17, losses -> 4)))
scala> sourceMap.map { case (team, innerMap) =>
| val outcomeGroups = innerMap.values.flatten.groupBy(_._1)
| team -> outcomeGroups.map { case (outcome, xs) =>
| val scores = xs.map(_._2).sum
| outcome -> scores
| }
| }
res0: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,Int]] = Map(team1 -> Map(losses -> 12, wins -> 33), team2 -> Map(losses -> 5, wins -> 39))