版權聲明:本文由董可倫首發于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(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)