Is there an idiomatic way to go from `Map<Key,`...
# stdlib
g
Is there an idiomatic way to go from
Map<Key,
Set<Value>>
to
Map<Value,
Key>
?
a
I don’t know a provided way to do it, but seems like you just need to do
Copy code
fun <Key, Value> Map<Key, Set<Value>>.invert(): Map<Value, Key> =
    entries.flatMap { (k, vs) -> vs.map { it to k } }.toMap()
1
g
Thank you. That looks much better than my current code 😅
k
Beware of the possibility of duplicates though. (i.e. a value being in more than one set).
e
I'd define
Copy code
fun <K, V> Map<K, Iterable<V>>.invert(): Map<V, K> = buildMap {
    for ((k, vs) in this@invert) {
        for (v in vs) put(v, k)
    }
}
just for fewer intermediary structures, but yes, this will result in losing duplicates
👍🏻 1
you can keep all the duplicates with things like
Copy code
fun <K, V> Map<K, Iterable<V>>.invert(): Map<V, Set<K>> = entries.asSequence()
    .flatMap { (k, vs) -> vs.asSequence().map(k::to) }
    .groupingBy { it.second }
    .fold(
        initialValueSelector = { _, (k, _) -> mutableSetOf(k) },
        operation = { _, set, (k, _) -> set.apply { add(k) } },
    )
of course