Scala 仅使用某些键映射

Scala 仅使用某些键映射,scala,Scala,对于Scala中的映射,如果ms-(k,1,m)返回包含所有ms映射的映射,但对于具有给定键x,1和m的任何映射,则返回 那么,什么语句将返回一个ms的所有映射的映射,其中只包含给定的键x、1和m。i、 我在寻找ms的子集,其中只有k、1和m是键 这是可行的,但很糟糕: scala> val originalMap = Map("age" -> "20", "name" -> "jack", "hobby" -> "jumping") ms: scala.collecti

对于Scala中的映射,如果
ms-(k,1,m)
返回包含所有ms映射的映射,但对于具有给定键x,1和m的任何映射,则返回

那么,什么语句将返回一个ms的所有映射的映射,其中只包含给定的键x、1和m。i、 我在寻找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)

filterKeys
可以帮助:

scala> originalMap.filterKeys(interestingKeys.contains)
res0: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> jack, hobby -> jumping)

因为<代码> FieldKys<代码>基于任意谓词的过滤器,它必须考虑映射中的每个键。这可能是好的,也可能不是,这取决于地图的大小,等等,但是对于您描述的操作来说,这绝对不是必需的。我会使用类似以下内容:

interestingKeys.flatMap(k => originalMap.get(k).map((k, _))).toMap
这将是
O(n)
O(n log m)
这取决于您的地图实现(其中
n
interestingKeys
的大小,
m
是地图的大小),而不是
O(m log n)
O(mn)

如果您确实需要
~
运算符,可以使用:


现在,
originalMap~(“name”,“hobby”)
返回
Map(name->jack,hobby->jumping)
,正如您所期望的那样。

我认为原始代码并没有那么糟糕,它可以很容易地转换为一行操作键集的代码:

val interestingMap = originalMap -- (originalMap.keySet -- interestingKeys)

我觉得这很可读。

兴趣键可能会有所改进。toSet`而不是
兴趣键包含
,因为将成员身份检查到集合中可能更有效。但是,不使用双元素列表。如果传递distinc元素列表,则不使用。这显然取决于上下文。为什么不同的元素会改变这一点?对于典型的set实现,成员资格测试仍然是O(n),而不是O(1)或O(logn)。不过,这有点令人惊讶,我本以为会有类似ms~(k,1,m)的东西其中~表示一个虚构的操作符,该操作符处理映射和列表之间的键的交集并返回结果映射。@didierd:是的,我后来找到了它。对于那些使用AKKA持久性的人,值得一提的是,
filterKeys
输出是不可序列化的,我面对了这个问题,花了一段时间才意识到这一点。看见
val interestingMap = originalMap -- (originalMap.keySet -- interestingKeys)