在给定 Kotlin 中的键列表的情况下切片地图

Slice a map given a list of keys in Kotlin

给定一张地图和一个键列表

val abc = mapOf(1 to "a", 2 to "b", 3 to "c")
val keys = listOf(1, 2)

如何获取仅包含 keys 指定的键值对的映射?像

val ab = abc.slice(keys)
// equivalent to mapOf(1 to "a", 2 to "b)

我正在寻找比

更优雅的东西
val ab = listOf(1, 2).map { it to abc[it] }.toMap()

例如,在 Elixir 中:

abc = %{1 => "a", 2 => "b", 3 => "c"}
ab = Map.take(abc, [1, 2])
# equivalent to ab = %{1 => "a", 2 => "b"}
abc.filterKeys { it in listOf(1, 2) }

您可以使用 filterKeys:

val ab = abc.filterKeys { it in keys }

而且由于它是 Kotlin,您甚至可以定义自己的 extension function 来实现您的想象:

fun <T> Map<T, *>.slice(keys: Iterable<T>) = filterKeys { it in keys }

val ab = abc.slice(keys)

以上答案中给出的解决方案确实解决了问题,但我认为有必要进行一些小改动。

问题是,对于 map 中的每个 key,他们检查 list contains 是否是 key,即 O(n)操作,这对于小列表是可以的,但是一旦达到一定大小,它就会变得非常慢。我建议您将键的 list 转换为 set,这在一般情况下会将包含操作减少为 O(1)。 (因此减少碳足迹 :))。

以下是包含上述更改的解决方案。

val mapAbc = mapOf(1 to "a", 2 to "b", 3 to "c")
val keySet = listOf(1, 2).toSet()
val filteredMap = mapAbc.filterKeys { it in keySet }