4

如何获取地图的子集?

假设我们有

val m: Map[Int, String] = ...
val k: List[Int]

其中所有键都k存在于m.

现在我想获得 Map 的一个子部分,m其中只有 key 在 list 中的对k

类似的东西m.intersect(k),但intersect没有在地图上定义。

一种方法是使用filterKeys: m.filterKeys(k.contains)。但这可能有点慢,因为对于原始映射中的每个键,都必须在列表中进行搜索。

我能想到的另一种方法是k.map(l => (l, m(l)).toMap。这里只是遍历我们真正感兴趣的键而不进行搜索。

有更好的(内置)方式吗?

4

3 回答 3

15
m filterKeys k.toSet

因为 aSetFunction.

关于性能filterKeys它本身是 O(1),因为它通过生成一个新的地图来工作,其中覆盖了、foreach和方法。访问元素时会产生开销。这意味着新地图不使用额外的内存,但也无法释放旧地图的内存。iteratorcontainsget

如果您需要释放内存并尽可能快地访问,一种快速的方法是将 的元素折叠k到一个新的 Map 中而不产生中间List[(Int,String)]

k.foldLeft(Map[Int,String]()){ (acc, x) => acc + (x -> m(x)) }
于 2012-08-27T18:09:09.063 回答
2

val s = Map(k.map(x => (x, m(x))): _*)

于 2012-08-28T06:56:13.553 回答
1

我认为这是最具可读性和表现最好的:

k zip (k map m) toMap

或者,方法调用样式将是:

k.zip(k.map(m)).toMap

于 2012-08-31T15:38:41.617 回答