簡體   English   中英

在 scala 中合並兩個具有相同鍵類型但不同值類型的 Map

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM