微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在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])))
})

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐