对于Scala中的地图,如果ms - (k, 1, m)
返回包含ms 的所有映射的地图,除了,用于具有给定键x,1和m的任何映射。
然后,什么语句将返回ms的所有映射的映射,其中仅给定的键x,1和m。即我正在寻找ms的子集,其中只有k,1和m是键。
这很有效,但很糟糕:
scala> val originalMap = Map("age" -> "20", "name" -> "jack", "hobby" -> "jumping")
ms: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(age -> 20, name -> jack, hobby -> jumping)
scala> val interestingKeys = List("name", "hobby")
interesting: List[java.lang.String] = List(name, hobby)
scala> val notInterestingMap = originalMap -- interestingKeys
notInterestingMap: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(age -> 20)
scala> val interestingMap = originalMap -- notInterestingMap.keySet
interestingMap: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> jack, hobby -> jumping)
答案 0 :(得分:7)
filterKeys
可以提供帮助:
scala> originalMap.filterKeys(interestingKeys.contains)
res0: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> jack, hobby -> jumping)
答案 1 :(得分:7)
由于filterKeys
基于任意谓词进行过滤,因此必须考虑地图中的每个键。这可能是好的或不是,取决于地图的大小等,但它绝对不是您描述的操作所必需的。我会使用以下内容:
interestingKeys.flatMap(k => originalMap.get(k).map((k, _))).toMap
这将是O(n)
或O(n log m)
,具体取决于您的地图实施情况(n
的大小为interestingKeys
而m
是地图的大小),而不是O(m log n)
或O(mn)
。
如果您真的想要~
运营商,可以使用pimp-my-library pattern:
class RichMap[A, B](m: Map[A, B]) {
def ~(ks: A*) = ks.flatMap(k => m.get(k).map((k, _))).toMap
}
implicit def enrichMap[A, B](m: Map[A, B]) = new RichMap(m)
现在originalMap ~ ("name", "hobby")
会返回Map(name -> jack, hobby -> jumping)
,正如您所期望的那样。
答案 2 :(得分:2)
我认为原始代码并没有那么糟糕,它可以很容易地转换为在关键集上运行的单行代码:
val interestingMap = originalMap -- (originalMap.keySet -- interestingKeys)
我觉得这很可读。