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
は加算演算子を使用するため、重複する各キーの値の合計を取得できます。
編集:user482745のリクエストに従って、もう少し詳細。
数学的には、セミグループは単なる値のセットであり、そのセットから2つの値を取り、そのセットから別の値を生成する演算子を備えています。たとえば、加算中の整数はセミグループです。たとえば、+
演算子は2つのintを結合して別のintを作成します。
また、2つのマップを組み合わせて何らかの方法で2つのマップを組み合わせた新しいマップを生成する操作を考え出すことができる限り、「特定のキータイプと値タイプのすべてのマップ」のセットにセミグループを定義することもできます。入力。
両方のマップに表示されるキーがない場合、これは簡単です。同じキーが両方のマップに存在する場合、キーがマップする2つの値を組み合わせる必要があります。うーん、同じタイプの2つのエンティティを組み合わせる演算子について説明しましたか?これがMap[K, V]
、Scalazでセミグループが存在するのは、セミグループが存在する場合にのみ存在する理由ですV
- V
のセミグループは、同じキーに割り当てられている2つのマップの値を組み合わせるために使用されます。
したがって、Int
ここでは値のタイプなので、1
キーの「衝突」は、2つのマッピングされた値の整数加算によって解決されます(これは、Intのセミグループ演算子が行うことと同じです)100 + 9
。値が文字列であった場合、衝突により2つのマップされた値の文字列連結が発生します(これも、文字列のセミグループ演算子が行うためです)。
(そして興味深いことに、文字列の連結は可換ではないため、つまり"a" + "b" != "b" + "a"
、結果のセミグループ操作map1 |+| map2
も異なります。したがってmap2 |+| map1
、文字列の場合とは異なりますが、Intの場合とは異なります。)
map1 ++ map2