I would like to group a list to a Map that contains every single key of an enum class. Consider the following example:
enum class E { A, B, C }
fun main() {
val l = listOf("Alice", "Anne", "Charlie")
val a = l.groupBy { E.valueOf(it.substring(0,1)) }
println(a)
}
As it is, groupBy returns {A=[Alice, Anne], C=[Charlie]}
.
I would like it to return {A=[Alice, Anne], B=[], C=[Charlie]}
.
I know I can create a function that iterates over all the entries of an enum and filters the list that way, thus creating what I want, but that's a very brute-force approach. Is there an existing function that does what I'm after, or a neat and concise way to do it?
One strategy would be to create a map of empty defaults and then fill it in using groupBy
.
val a2: Map<E, List<String>> = E.entries.associateWith { emptyList<String>() } +
l.groupBy { E.valueOf(it.substring(0,1)) }
val a3: Map<Char, List<String>> = a2.mapKeys { (key, _) -> key.name.first() }
This is using valueOf
and I'm not sure of the time complexity of how it's implemented in the JVM so it may or may not be considered brute force itself. I suppose you could ensure it's not by creating a map first.
val entriesByName = E.entries.associateBy(E::name)
val a2: Map<E, List<String>> = E.entries.associateWith { emptyList<String>() } +
l.groupBy { entriesByName.getValue(it.substring(0,1)) }