[英]scala: union of two maps whose key type is the same and whose value type is a collection of elements, but whose types are different
[英]Combine two Maps with same key type, but different value type in scala
我想將兩個具有相同類型鍵但不同類型值的 Map 組合起來。
結果應該具有包含兩種值類型的值(可選,因為某些值可能僅存在於一個輸入映射中)
類型注釋是
def combineMaps[T, U, V](map1: Map[T, U], map2: Map[T, V]): Map[T, (Option[U], Option[V])] = {
???
}
我知道它可以通過復雜的代碼來實現,例如:
(map1.mapValues(Some(_) -> None).toList ++ map2.mapValues(None -> Some(_)).toList) // List[(T, (Option[U], Option[V]))]
.groupBy(_._1) // Map[T, List[(T, (Option[U], Option[V]))]]
.mapValues(_.map(_._2)) // Map[T, List[(Option[U], Option[V])]]
.mapValues { list => (
list.collectFirst { case (Some(u), _) => u },
list.collectFirst { case (_, Some(v)) => v }
) } // Map[T, (Option[U], Option[V])]
盡管代碼可以運行,但它並沒有受益於 Map 中的每個鍵只出現一次這一事實。 方法.toList
刪除此類型信息。
我正在尋找一些優雅的 scala 方式來做到這一點(可能與貓/scalaz,但最好沒有它們)
是的,貓有你介紹過,這就是Align
類型類提供的。
你只需要做:
m1.align(m2)
這將返回一個比一對Options
更好的Map[T, Ior[U, V]]
,因為Ior
保留了兩個元素中至少一個必須存在的事實。
keySet
的聯合,然后將鍵映射到get
的元組應該這樣做:
def combineMaps[T, U, V](m1: Map[T, U], m2: Map[T, V]): Map[T, (Option[U], Option[V])] =
(m1.keySet union m2.keySet).map(k => (k, (m1.get(k), m2.get(k)))).toMap
例子:
combineMaps(Map('a'->1, 'b'->2, 'c'->3), Map('a'->10.0, 'c'->30.0, 'd'->40.0))
// res1: Map[Char,(Option[Int], Option[Double])] = Map(
// a -> (Some(1),Some(10.0)), b -> (Some(2),None), c -> (Some(3),Some(30.0)), d -> (None,Some(40.0))
// )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.