scala合并两个可变集的可变映射的最佳方法是什么?该操作必须是可交换的。我尝试过的东西看起来很难看......
import scala.collection.mutable
var d1 = mutable.Map[String, mutable.SortedSet[String]]()
var d2 = mutable.Map[String, mutable.SortedSet[String]]()
// adding some elements. Accumulating nimals with the set of sounds they make.
d1.getOrElseUpdate("dog", mutable.SortedSet[String]("woof"))
d2.getOrElseUpdate("cow", mutable.SortedSet[String]("moo"))
d2.getOrElseUpdate("dog", mutable.SortedSet[String]("woof", "bark"))
魔法(这是可交换的!)
scala.collection.mutable.Map[String,scala.collection.mutable.SortedSet[String]] =
Map(dog -> TreeSet(bark, woof), cow -> TreeSet(moo))
基本上,我想覆盖++的定义来合并匹配地图键的集合。请注意 d1 ++ d2给出了正确的答案,而d2 ++ d1则没有(因此++在这里不可交换)。
答案 0 :(得分:2)
对于结果Map
中的每个键,您必须合并(++
)来自Set
和d1
的值d2
那把钥匙。
对于mutable.Map
和mutable.Set
,当您更新其中一个Map
时,实施非常简单:
for ((key, values) <- d2)
d1.getOrElseUpdate(key, mutable.SortedSet.empty) ++= values
您实际上可以创建一个空的mutable.Map
,并使用该代码以任意顺序使用d1
和d2
(以及其他Map
s)进行更新。
您可以将此操作包装在以下函数中:
val d1 = mutable.Map[String, mutable.SortedSet[String]](
"dog" -> mutable.SortedSet("woof"),
"cow" -> mutable.SortedSet("moo"))
val d2 = mutable.Map[String, mutable.SortedSet[String]](
"dog" -> mutable.SortedSet("woof", "bark"))
def updateMap[A, B : Ordering]( // `Ordering` is a requirement for `SortedSet`
d1: mutable.Map[A, mutable.SortedSet[B]])(
// `Iterable`s are enough here, but allow to pass a `Map[A, Set[B]]`
d2: Iterable[(A, Iterable[B])]
): Unit =
for ((key, values) <- d2)
d1.getOrElseUpdate(key, mutable.SortedSet.empty) ++= values
// You can call
// `updateMap(d1)(d2)` or
// `updateMap(d2)(d1)` to achieve the same result (but in different variables)
对于不可变的Map
,一种可能的实现是:
(
for (key <- d1.keySet ++ d2.keySet)
yield key -> (d1.getOrElse(key, Set.empty) ++ d2.getOrElse(key, Set.empty))
).toMap
其他可能更有效但可能稍微复杂的实现也是可能的。