如何在Scala的Map List中按键值对值进行求和并对它们进行分组?

我有一张地图清单:

val list = List(
  Map("id" -> "A","value" -> 20,"name" -> "a"),Map("id" -> "B","value" -> 10,"name" -> "b"),Map("id" -> "A","value" -> 5,Map("id" -> "C","value" -> 1,"name" -> "c"),Map("id" -> "D","value" -> 60,"name" -> "d"),"value" -> 3,"name" -> "c")
)

我想对值进行求和,并以最有效的方式将它们按id值分组,以便它变为:

Map(A -> 25,B -> 10,C -> 4,D -> 60)

解决方法

还使用foldLeft:

list.foldLeft(Map[String,Int]().withDefaultValue(0))((res,v) => {
  val key = v("id").toString
  res + (key -> (res(key) + v("value").asInstanceOf[Int]))
})

更新:使用reduceLeft:

(Map[String,Any]().withDefaultValue(0) :: list).reduceLeft((res,v) => {
  val key = v("id").toString
  res + (key -> (res(key).asInstanceOf[Int] + v("value").asInstanceOf[Int]))
})

顺便说一句,如果你看一下reduceLeft定义,你会看到它使用相同的foldLeft:

def reduceLeft[B >: A](f: (B,A) => B): B =
    if (isEmpty) throw new UnsupportedOperationException("empty.reduceLeft")
    else tail.foldLeft[B](head)(f)

更新2:使用par和reduce:
这里的问题是将结果Map值与初始Map值区分开来.我选择了contains(“id”).

list.par.reduce((a,b) => {
  def toResultMap(m: Map[String,Any]) =
    if (m.contains("id"))
      Map(m("id").toString -> m("value")).withDefaultValue(0)
    else m
  val aM = toResultMap(a)
  val bM = toResultMap(b)
  aM.foldLeft(bM)((res,v) =>
    res + (v._1 -> (res(v._1).asInstanceOf[Int] + v._2.asInstanceOf[Int])))
})

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...