scala 两个map合并,key相同时value相加

版权声明:本文由董可伦首发于https://dongkelun.com,非商业转载请注明作者及原创出处。商业转载请联系作者本人。 https://blog.csdn.net/dkl12/article/details/80246048

我的原创地址:https://dongkelun.com/2018/04/01/scalaMapAdd/

1、先看一下map自带的合并操作的效果

val map1 = Map("key1" -> 1, "key2" -> 3, "key3" -> 5)
val map2 = Map("key2" -> 4, "key3" -> 6, "key5" -> 10)
println(map1 + ("key1" -> 3))
println(map1 ++ map2)

结果:

Map(key1 -> 3, key2 -> 3, key3 -> 5)
Map(key1 -> 1, key2 -> 4, key3 -> 6, key5 -> 10)

可以看到现有的方法在key相同时,没有将value相加,而是操作符右边的值把左边的值覆盖掉了。

2、利用map函数

2.1 为了便于理解先看如下代码

代码:

val map1 = Map("key1" -> 1, "key2" -> 3, "key3" -> 5)
map1.map { t => println(t._1, t._2) }

结果:

(key1,1)
(key2,3)
(key3,5)

可以看出map函数会遍历集合中的每个元素
可以为其指定返回结果:

println(map1.map { t => 2 })
println(map1.map { t => t._1 -> t._2 })

结果:

List(2, 2, 2)
Map(key1 -> 1, key2 -> 3, key3 -> 5)

可以看出,该函数返回结果类型可以不同,并且会将我们指定的值,组成一个集合,并自动判断返回类型。

2.2 合并两个map

val map1 = Map("key1" -> 1, "key2" -> 3, "key3" -> 5)
val map2 = Map("key2" -> 4, "key3" -> 6, "key5" -> 10)
val mapAdd1 = map1 ++ map2.map(t => t._1 -> (t._2 + map1.getOrElse(t._1, 0)))
println(mapAdd1)

其中map.getOrElse(key,default):如果map中有这个key,则返回对应的value,否在返回default
结果:

Map(key1 -> 1, key2 -> 7, key3 -> 11, key5 -> 10)

3、用foldLeft

3.1 语法

以下三种写法是相等的:

List(1, 2, 3, 4).foldLeft(0)((sum, i) => sum + i)
(List(1, 2, 3, 4) foldLeft 0)((sum, i) => sum + i)
(0 /: List(1, 2, 3, 4))(_ + _)  

为了便于理解,先看下面代码:

(0 /: List(1, 2, 3, 4))((sum, i) => {
  println(s"sum=${sum} i=${i}")
  sum
})

结果:

sum=0 i=1
sum=0 i=2
sum=0 i=3
sum=0 i=4

该函数的功能是从左往右遍历右边操作类型List,而sum对应的是对应的左边的0,该函数要求返回值类型和左边类型一致,上面的例子中返回值是Int。
同理,两个Map的代码如下:

val map1 = Map("key1" -> 1, "key2" -> 3, "key3" -> 5)
val map2 = Map("key2" -> 4, "key3" -> 6, "key5" -> 10)
(map1 /: map2)((map, kv) => {
  println(s"map=${map} kv=${kv}")
  map
})

结果:

map=Map(key1 -> 1, key2 -> 3, key3 -> 5) kv=(key2,4)
map=Map(key1 -> 1, key2 -> 3, key3 -> 5) kv=(key3,6)
map=Map(key1 -> 1, key2 -> 3, key3 -> 5) kv=(key5,10)

从结果中可以看出左边map对应的是map1整体,而不是遍历map1

3.2 合并两个map:

val map1 = Map("key1" -> 1, "key2" -> 3, "key3" -> 5)
val map2 = Map("key2" -> 4, "key3" -> 6, "key5" -> 10)
val mapAdd2 = (map1 /: map2)((map, kv) => {
  map + (kv._1 -> (kv._2 + map.getOrElse(kv._1, 0)))
})
println(mapAdd2)

其中map.getOrElse(key,default):如果map中有这个key,则返回对应的value,否在返回default
结果:

Map(key1 -> 1, key2 -> 7, key3 -> 11, key5 -> 10)

4、用模式匹配

在网上查的有的用的模式匹配,我感觉在这里这样用就是多余~
附上代码:

val mapAdd2 = map1 ++ map2.map { case (key, value) => key -> (value + map1.getOrElse(key, 0)) }
println(mapAdd2)
val mapAdd3 = (map1 /: map2) {
  case (map, kv) => {
    map + (kv._1 -> (kv._2 + map.getOrElse(kv._1, 0)))
  }
}
println(mapAdd3)
val mapAdd4 = (map1 /: map2) {
  case (map, (k, v)) => {
    map + (k -> (v + map.getOrElse(k, 0)))
  }
}
println(mapAdd4)

结果是一样的:

Map(key1 -> 1, key2 -> 7, key3 -> 11, key5 -> 10)
Map(key1 -> 1, key2 -> 7, key3 -> 11, key5 -> 10)
Map(key1 -> 1, key2 -> 7, key3 -> 11, key5 -> 10)

参考

https://www.cnblogs.com/tugeler/p/5134862.html

上一篇:Py之GraphLab:graphlab库的简介、安装、使用方法之详细攻略


下一篇:转一篇NGINX+UWSGI+PYTHON+DJANGO部署文档