从Map [String,List [Int]]折叠到Map [String,Int]

时间:2014-09-02 21:53:41

标签: scala

我对Scala和一般的功能方法都很新。我有一个看起来像这样的地图:

val myMap: Map[String, List[Int]]

我希望最终能够将密钥映射到关联列表的总数:

val totalsMap: Map[String, Int]

我最初的预感是使用理解:

val totalsMap = for (kvPair <- myMap) {
    kvPair._2.foldLeft(0)(_+_)
}

但是我不知道我会在yield()子句中添加什么来获得for for comprehension的地图。

3 个答案:

答案 0 :(得分:5)

您可以使用mapValues,

val totalMap = myMap.mapValues(_.sum)

但是mapValues会在每次从Map获取密钥时重新计算总和。例如如果多次执行totalMap(“a”),则每次都会重新计算总和。

如果你不想这样,你应该使用

val totalMap = myMap map { 
  case (k, v) => k -> v.sum
}

答案 1 :(得分:2)

mapValues更适合这种情况:

val m = Map[String, List[Int]]("a" -> List(1,2,3), "b" -> List(4,5,6))

m.mapValues(_.foldLeft(0)(_+_))

res1: scala.collection.immutable.Map[String,Int] = Map(a -> 6, b -> 15)

或没有foldLeft

m.mapValues(_.sum)

答案 2 :(得分:1)

val m = Map("hello" -> Seq(1, 1, 1, 1), "world" -> Seq(1, 1))
for ((k, v) <- m) yield (k, v.sum)

产量

Map(hello -> 4, world -> 2)`

for comprehension将返回你给它的任何monadic类型。在这种情况下,mMap,因此即将发布的内容。 yield必须返回一个元组。第一个元素(成为每个Map条目中的键)是您正在计算的单词,第二个元素(您猜对了,每个Map条目中的值)成为总和最初的计数序列。