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

转载请务必注明原创地址为:http://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

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C/C++基础

C/C++结构体初始化与赋值

结构体是常用的自定义构造类型,是一种很常见的数据打包方法。结构体对象的初始化有多种方式,分为指定初始化、顺序初始化、构造函数初始化。假如有如下结构体。

1542
来自专栏WindCoder

求十个数中最大值和最小值-C++

2731
来自专栏技术之路

c++返回值 注意事项

1.不要返回指向局部变量或临时对象的引用。函数执行完毕后,局部变量和临时对象会消失,引用将指向不存在的数据 2.返回指向const对象的引用    使用cons...

19510
来自专栏专注数据中心高性能网络技术研发

[C++]C++面试知识总结

1.程序运行知识 1.1 内存布局和分配方式 C程序的内存布局如下: ? 静态存储区:存储全局变量和static变量,通常在程序编译期间已经分配好了。 BSS...

3154
来自专栏不想当开发的产品不是好测试

nodejs 语法学习(持续更新)

合并objects var o1 = { a: 1 }; var o2 = { b: 2 }; var o3 = { c: 3 }; var obj = Ob...

22910
来自专栏鸿的学习笔记

python类的继承与运算符重载

Officially, CPython has no rule at all for when exactly overridden method of sub...

751
来自专栏Python

python ——面向对象进阶

1.staticmethod和classmethod staticmethod  静态方法: 让类里的方法,直接被类调用,就像正常的函数一样 宝宝,男 博博,女...

1987
来自专栏IT笔记

JAVA中基本数据类型和引用数据类型特点

特点: 一、从概念方面来说 基本数据类型:变量名指向具体的数值 引用数据类型:变量名指向存数据对象的内存地址,即变量名指向hash值 二、从内存构建方面来说...

2748
来自专栏Python小屋

Python提取任意长度整数的每位数字

问题描述:编写函数,给定一个任意长度整数,返回每位数字,例如给定1234则返回(1, 2, 3, 4)。问题本身并不复杂,主要演示Python运算符和内置函数的...

3035
来自专栏函数式编程语言及工具

泛函编程(16)-泛函状态-Functional State

    初接触泛函状态觉着很不习惯。主要是在使用State数据类型时很难理解其中的原理,特别是泛函状态变迁机制(state transition mechani...

20710

扫码关注云+社区