Scalaz memiliki konsep Semigroup yang menangkap apa yang ingin Anda lakukan di sini, dan mengarah pada solusi terpendek / terbersih:
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)
Secara khusus, operator biner untuk Map[K, V]
menggabungkan kunci peta, melipat V
operator semigroup atas nilai duplikat apa pun. Semigroup standar untuk Int
menggunakan operator tambahan, sehingga Anda mendapatkan jumlah nilai untuk setiap kunci duplikat.
Sunting : Sedikit lebih detail, sesuai permintaan pengguna482745.
Secara matematis sebuah semi -grup hanyalah satu set nilai, bersama dengan operator yang mengambil dua nilai dari set itu, dan menghasilkan nilai lain dari set itu. Jadi bilangan bulat yang ditambahkan adalah semigroup, misalnya - +
operator menggabungkan dua int untuk membuat int lainnya.
Anda juga dapat mendefinisikan sebuah semi grup dari set "semua peta dengan tipe kunci dan tipe nilai yang diberikan", asalkan Anda dapat membuat beberapa operasi yang menggabungkan dua peta untuk menghasilkan yang baru yang entah bagaimana merupakan kombinasi dari keduanya. input.
Jika tidak ada kunci yang muncul di kedua peta, ini sepele. Jika kunci yang sama ada di kedua peta, maka kita perlu menggabungkan dua nilai yang dipetakan oleh kunci tersebut. Hmm, bukankah kita baru saja menggambarkan operator yang menggabungkan dua entitas dari jenis yang sama? Inilah sebabnya mengapa dalam Scalaz, sebuah semi-grup untuk Map[K, V]
ada jika dan hanya jika semi-grup untuk V
ada - semi-grup V
digunakan untuk menggabungkan nilai-nilai dari dua peta yang ditugaskan untuk kunci yang sama.
Jadi karena Int
jenis nilai di sini, "tabrakan" pada 1
kunci diselesaikan dengan penambahan integer dari dua nilai yang dipetakan (seperti yang dilakukan oleh operator semi-grup Int), karenanya 100 + 9
. Jika nilainya adalah String, tabrakan akan menghasilkan rangkaian string dari dua nilai yang dipetakan (sekali lagi, karena itulah yang dilakukan oleh operator semi-grup untuk String).
(Dan yang menarik, karena rangkaian string tidak komutatif - yaitu, "a" + "b" != "b" + "a"
- operasi semigroup yang dihasilkan juga tidak. Jadi map1 |+| map2
berbeda dari map2 |+| map1
dalam kasus String, tetapi tidak dalam kasus Int.)
map1 ++ map2