Is there a method to convert a `List` to a `Map` b...
# getting-started
c
Is there a method to convert a
List
to a
Map
but where each initial element that lead to multiple keys?
Copy code
class A
class B

data class C(
    val a: List<A>,
    val b: B,
)

val input: List<C> = …
val output: Map<A, List<B>> = input.???
There is
.groupBy
which does the opposite (each item can create multiple values), but I'm searching for the case where each item can be put into the list in different places. I guess I can do
Copy code
val output: Map<A, List<B>> = input.fold(HashMap<A, ArrayList<B>>()) { acc, it ->
    for (a in it.a) {
        acc.merge(a, arrayListOf(it)) { a, b -> a.addAll(b); a }
    }
    acc
}
but that's not very elegant
s
I'd start by flattening
List<C>
into a list of individual key-value pairs:
Copy code
val pairs = input.flatMap { (aa, b) -> aa.map { a -> a to b } }
val output = pairs.groupBy({ it.first }, { it.second })
I'm not sure it's clearer than what you already had, though...
1
y
If you make your fold into a
buildMap
call, I think it'll be clear enough
p
Copy code
val output: Map<A, List<B>> = buildMap<A, MutableList<B>> {
        for((aa, b) in input) {
            for(a in aa) {
                getOrPut(a, { mutableListOf<B>() }).add(b)
            }
        }
    }
fairly clear of intent
👍 2
1