14

在 Scala 中压缩两个字典的实用方法是什么?

map1 = new HashMap("A"->1,"B"->2)
map2 = new HashMap("B"->22,"D"->4) // B is the only common key

zipper(map1,map2)应该给出类似的东西

 Seq( ("A",1,0), // no A in second map, so third value is zero
      ("B",2,22),
      ("D",0,4)) // no D in first map, so second value is zero 

如果没有功能,任何其他风格也值得赞赏

4

2 回答 2

19
def zipper(map1: Map[String, Int], map2: Map[String, Int]) = {
  for(key <- map1.keys ++ map2.keys)
    yield (key, map1.getOrElse(key, 0), map2.getOrElse(key, 0))
}


scala> val map1 = scala.collection.immutable.HashMap("A" -> 1, "B" -> 2)
map1: scala.collection.immutable.HashMap[String,Int] = Map(A -> 1, B -> 2)

scala> val map2 = scala.collection.immutable.HashMap("B" -> 22, "D" -> 4)
map2: scala.collection.immutable.HashMap[String,Int] = Map(B -> 22, D -> 4)

scala> :load Zipper.scala
Loading Zipper.scala...
zipper: (map1: Map[String,Int], map2: Map[String,Int])Iterable[(String, Int, Int)]

scala> zipper(map1, map2)
res1: Iterable[(String, Int, Int)] = Set((A,1,0), (B,2,22), (D,0,4))

在这种情况下,注意使用get可能更可取。用于指定一个值不存在,而不是使用.getOrElseNone0

于 2013-04-28T00:41:25.110 回答
0

作为布赖恩答案的替代方案,这可以通过隐式方法用于增强地图类:

implicit class MapUtils[K, +V](map: collection.Map[K, V]) {
  def zipAllByKey[B >: V, C >: V](that: collection.Map[K, C], thisElem: B, thatElem: C): Iterable[(K, B, C)] =
  for (key <- map.keys ++ that.keys)
    yield (key, map.getOrElse(key, thisElem), that.getOrElse(key, thatElem))
}

命名和 API 与序列相似zipAll

于 2021-04-24T06:29:30.623 回答