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 条评论
登录 后参与评论

相关文章

来自专栏mukekeheart的iOS之旅

OC学习2——C语言特性之函数

1、OC是在C语言的基础上进行扩展的,在OC中直接用C语言进行coding也是可以通过编译的。因此,函数定义的语法格式如下: 函数返回值类型 函数名(形参列表...

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

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

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

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

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

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

34640
来自专栏IT笔记

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

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

30080
来自专栏Python小屋

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

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

37250
来自专栏算法修养

pta 习题集 5-2 找出不是两个数组共有的元素 (5分)

给定两个整型数组,本题要求找出不是两者共有的元素。 输入格式: 输入分别在两行中给出两个整型数组,每行先给出正整数NN(≤20≤20),随后是NN个整数,...

550100
来自专栏鸿的学习笔记

python类的继承与运算符重载

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

11210
来自专栏技术之路

c++返回值 注意事项

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

201100
来自专栏java一日一条

Java内部类

这样看起来,类Draw像是类Circle的一个成员,Circle称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静...

12210
来自专栏黑泽君的专栏

c语言基础学习07_指针

=============================================================================

28800

扫码关注云+社区

领取腾讯云代金券