如何获取地图的子集?
假设我们有
val m: Map[Int, String] = ...
val k: List[Int]
k
中m
中的所有键都存在。
现在,我想获得一个地图m
的子部分,其中只包含哪个键位于列表k
中。
类似于m.intersect(k)
,但地图上未定义intersect
。
一种方法是使用filterKeys
:m.filterKeys(k.contains)
。但这可能有点慢,因为对于原始地图中的每个键,必须在列表中进行搜索。
我能想到的另一种方式是k.map(l => (l, m(l)).toMap
。这里只是遍历我们真正感兴趣的键,不进行搜索。
有更好的(内置)方式吗?
答案 0 :(得分:14)
m filterKeys k.toSet
因为Set
是Function
。
关于效果:
filterKeys
本身就是O(1),因为它的工作原理是生成一个覆盖foreach
,iterator
,contains
和get
方法的新地图。访问元素时会产生开销。这意味着新地图不使用额外的内存,但也无法释放旧地图的内存。
如果您需要释放内存并尽可能快地访问,快速的方法是将k
的元素折叠到新地图中,而不会产生中间List[(Int,String)]
:
k.foldLeft(Map[Int,String]()){ (acc, x) => acc + (x -> m(x)) }
答案 1 :(得分:2)
val s = Map(k.map(x => (x, m(x))): _*)
答案 2 :(得分:1)
我认为这是最可读和最好的表演者:
k zip (k map m) toMap
或者,方法调用样式为:
k.zip(k.map(m)).toMap