給定兩張地圖
val m1 = Map("a" -> "a")
val m2 = Map("a" -> 1)
由于合并這兩者,我想得到
Map("a" -> ("a",1))
我為此嘗試了半群貓,它幾乎完成了作業,但是我必須自己為半群創建實體,就像這樣
Semigroupal.catsSemigroupalForMap[String]
然后將它們與product方法合并。我需要做什么才能不手動創建它?例如,合并兩個選項很簡單
val noneInt: Option[Int] = None
val some3: Option[Int] = Some(3)
Semigroupal[Option].product(noneInt, some)
我想實作一個類似的代碼來合并兩個地圖,但是在定義時
Semigroupal[Map]
編譯器找不到它的任何隱式。
uj5u.com熱心網友回復:
tupled 似乎可以解決問題:
@ val mapA = Map(1 -> 2)
mapA: Map[Int, Int] = Map(1 -> 2)
@ val mapB = Map(1 -> "b")
mapB: Map[Int, String] = Map(1 -> "b")
@ (mapA, mapB).tupled
res4: Map[Int, (Int, String)] = Map(1 -> (2, "b"))
它一般編譯:
@ def mergeMaps[A, B, C](m1: Map[A, B], m2: Map[A, C]): Map[A, (B, C)] = (m1, m2).tupled
defined function mergeMaps
@ mergeMaps(mapA, mapB)
res6: Map[Int, (Int, String)] = Map(1 -> (2, "b"))
它會銷毀不在兩個映射中的鍵:
@ val m1 = Map("a" -> "foo", "b" -> "bar")
m1: Map[String, String] = Map("a" -> "foo", "b" -> "bar")
@ val m2 = Map("a" -> 1, "c" -> 3)
m2: Map[String, Int] = Map("a" -> 1, "c" -> 3)
@ mergeMaps(m1, m2)
res9: Map[String, (String, Int)] = Map("a" -> ("foo", 1))
uj5u.com熱心網友回復:
這似乎是一個很好的用例 Align
import cats.data.Ior
import cats.syntax.all._
def combineMaps[K, A, B](m1: Map[K, A], m2: Map[K, B]): Map[K, (A, B)] =
m1.align(m2).collect {
case (key, Ior.Both(a, b)) => key -> (a, b)
}
可以這樣使用:
val m1 = Map("a" -> "foo", "b" -> "bar")
val m2 = Map("a" -> 1, "c" -> 3)
val result = combineMaps(m1, m2)
// result: Map[String, (String, Int)] = Map("a" -> ("foo", 1))
您可以在此處看到運行的代碼。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/358576.html
