is there a better way to turn a List of Maps into ...
# getting-started
b
is there a better way to turn a List of Maps into a single map with all of their values combined on the same index than this:
Copy code
val increaseSkills: List<Map<KingdomSkill, Set<KingdomSkill>>> = emptyList()
    val groupedSkills = mutableMapOf<KingdomSkill, Set<KingdomSkill>>()
    increaseSkills.forEach { map ->
        map.forEach { (skill, skills) ->
            groupedSkills.put(skill, (groupedSkills[skill] ?: emptySet()) + skills)
        }
    }
1
w
Something in the lines of
.flatMap { it.entries }.toMap()
?
b
oh, you're totally right
but the entries need to be grouped by key and values need to be combined
ok, I think I can manage that
thank you!
s
I think:
Copy code
increaseSkills
    .flatMap { it.entries }
    .groupBy({ it.key }, { it.value })
    .mapValues { it.value.flatten().toSet() }
But sometimes the explicit way is more readable!
b
more readable but those places tend to have more bugs as well
didn't know the value selector and mapValues method yet, thank you
m
If you go with the original, I would look at using
buildMap
instead of declaring a mutableMap. And I find this a little cleaner
groupedSkills[skill].orEmpty() + skills
than
(groupedSkills[skill] ?: emptySet()) + skills
But both of those are really just preferences.
b
thank you, .orEmpty() is great
I need to autocomplete on nullable types more often
m
Copy code
increaseSkills.reduce() { acc, map -> map + acc.mapValues { (k, v) -> v + map[k].orEmpty() } }
b
last lambda is the conflict/merge function?
m
Yes
b
thanks, that's the best one so far 🙂
🤟 1
can't find combine, is that only available on the jvm?
m
Ouch, this is embarrassing. I seem to have used a function from Arrow w/o realizing 😬
b
Monoid one?
m
it's from arrow-core
I'll do another one that doesn't use arrow shortly 😄
b
heh
yeah, I was looking for some combine/merge method/function
in Java there's Map.merge
m
Not as pretty, but:
Copy code
increaseSkills.reduce() { acc, map -> map + acc.mapValues { (k, v) -> v + map[k].orEmpty() } }
🙌 1
b
thanks
👍 1