【问题标题】:scala: best way to merge two mutable maps of mutable setsscala:合并两个可变集的可变映射的最佳方法
【发布时间】:2016-08-30 02:09:32
【问题描述】:

在 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 没有(所以 ++ 在这里不是可交换的)。

【问题讨论】:

  • 为什么是可变的?您想用另一张地图的值更新其中一张地图吗?
  • 想一想,我可能也可以使用不可变的。 Mutable 对我如何使用它更有意义。见编辑

标签: scala scala-collections


【解决方案1】:

对于结果 Map 中的每个键,您必须合并 (++) 来自该键的 d1d2 的值 Sets。

对于mutable.Maps 和mutable.Sets,当您更新Maps 之一时,实现非常简单:

for ((key, values) <- d2) 
  d1.getOrElseUpdate(key, mutable.SortedSet.empty) ++= values

您实际上可以创建一个空的mutable.Map,并使用该代码以任意顺序将其更新为d1d2(以及其他Maps,如果需要)。

您可以将此操作包装在以下函数中:

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)

对于不可变的Maps,一种可能的实现是:

(
  for (key <- d1.keySet ++ d2.keySet)
  yield key -> (d1.getOrElse(key, Set.empty) ++ d2.getOrElse(key, Set.empty))
).toMap

其他可能更有效,但可能稍微复杂一些的实现也是可能的。

【讨论】:

    猜你喜欢
    • 2018-08-23
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    • 2017-03-29
    • 1970-01-01
    • 2018-06-12
    • 2017-10-10
    • 1970-01-01
    相关资源
    最近更新 更多