简体   繁体   English

反转地图<K, List<V> &gt; 到地图<V, K>

[英]Invert Map<K, List<V>> to Map<V, K>

map = mapOf((2: [3,4,5]), (7: [22,33,44]))

need to convert this to需要将其转换为

mapOf(3:2, 4:2, 5:2, 22:7, 33:7, 44:7)

tried using associate with forEach, not sure of the syntax尝试使用与 forEach 关联,不确定语法

There might be some nicer syntax, but this should work well enough.可能有一些更好的语法,但这应该足够好。

fun main() {
    val map = mapOf(
        2 to listOf(3, 4, 5),
        7 to listOf(22, 33, 44)
    )
    val transformedMap = map.flatMap { entry ->
        entry.value.map { it to entry.key }
    }.toMap()
    println(transformedMap)
}

Prints {3=2, 4=2, 5=2, 22=7, 33=7, 44=7}打印{3=2, 4=2, 5=2, 22=7, 33=7, 44=7}

Note that the toMap function states请注意toMap函数状态

The returned map preserves the entry iteration order of the original collection.返回的映射保留原始集合的条目迭代顺序。 If any of two pairs would have the same key the last one gets added to the map.如果两对中的任何一对具有相同的键,则最后一对被添加到映射中。

So if you have the same value in two different lists, only the last one will be included in the map.因此,如果您在两个不同的列表中具有相同的值,则只有最后一个会包含在地图中。

fun main() {
    val map = mapOf(
        2 to listOf(3, 4, 5),
        7 to listOf(22, 33, 44),
        8 to listOf(3)
    )
    val transformedMap = map.flatMap { entry ->
        entry.value.map { it to entry.key }
    }.toMap()
    println(transformedMap)
}

Prints {3=8, 4=2, 5=2, 22=7, 33=7, 44=7}打印{3=8, 4=2, 5=2, 22=7, 33=7, 44=7}

Zymus' answer is correct, and is also what I would probably write. Zymus 的回答是正确的,也是我可能会写的。

However, if this is something that will be called often, you might want to extract it to a separate function that is more efficient.但是,如果这是经常调用的东西,您可能希望将其提取到一个更有效的单独函数中。

fun <K, V> Map<K, Iterable<V>>.invert(): Map<V, K> {
    val newMap = mutableMapOf<V, K>()
    for ((key, iterable) in this) {
        for (value in iterable) {
            newMap[value] = key
        }
    }
    return newMap
}

Usage:用法:

fun main() {
    val map = mapOf((2 to listOf(3, 4, 5)), (7 to listOf(22, 33, 44)))
    val inverted = map.invert()
    println(inverted)
}

Output:输出:

{3=2, 4=2, 5=2, 22=7, 33=7, 44=7}

This is functionally equivalent to这在功能上等同于

map.flatMap { (key, values) -> values.map { it to key } }.toMap()

including the behaviour where if there are duplicate values in the original input, only the last one will be preserved as a new key.包括如果原始输入中有重复值的行为,则只有最后一个将保留为新键。 However, the flatMap version creates many temporary List s (the number of original keys + 1) and many temporary Pair s (the number of original values), whereas this iterative version creates no extra objects.然而, flatMap版本创建了许多临时List (原始键的数量 + 1)和许多临时Pair (原始值的数量),而这个迭代版本没有创建额外的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM