Scalaz有一个概念半群什么你想在这里做的捕获,并导致无疑是最短/干净的解决方案:
scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> val map1 = Map(1 -> 9 , 2 -> 20)
map1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 9, 2 -> 20)
scala> val map2 = Map(1 -> 100, 3 -> 300)
map2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 100, 3 -> 300)
scala> map1 |+| map2
res2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 109, 3 -> 300, 2 -> 20)
具体来说,用于Map[K, V]
合并映射键的二进制运算符,将V
的半组运算符折叠到任何重复值上。标准半组Int
使用加法运算符,因此您将获得每个重复键的值之和。
编辑:根据用户482745的要求,提供更多细节。
从数学上讲,半群只是一组值,以及一个运算符,该运算符从该集中获取两个值,并从该集中产生另一个值。因此,加法+
运算中的整数是一个半群,例如- 运算符将两个int合并为另一个int。
您还可以在“具有给定键类型和值类型的所有映射”的集合上定义一个半组,只要您能提出一些操作,将两个映射组合在一起以生成一个新映射,这就是两者的组合输入。
如果两个地图中都没有按键,这是微不足道的。如果两个映射中都存在相同的键,那么我们需要组合键映射到的两个值。嗯,我们不是刚刚描述了一个将两个相同类型的实体组合在一起的运算符吗?这就是为什么在Scalaz一个半群Map[K, V]
当且仅当一个半群的存在,V
存在- V
的半群用于将值从被分配到相同的密钥两张地图结合起来。
因此,因为Int
这里是值类型,所以1
键上的“冲突” 是通过两个映射值的整数相加来解决的(因为这是Int的半组运算符所做的事情)100 + 9
。如果值是Strings,则冲突将导致两个映射值的字符串串联(同样,因为这是String的半组运算符所做的事情)。
(有趣的是,因为字符串连接是不可交换的-那就是"a" + "b" != "b" + "a"
-生成的半群操作也不那么,map1 |+| map2
是从不同map2 |+| map1
的字符串的情况下,而不是在诠释情况。)
map1 ++ map2