Reputation: 452
Baby Kotlin dev here :)
Considering the following structure:
[
{ "color": ["red", "blue"] },
{ "color": ["red", "green"] },
{ "shape": ["square", "circle"] },
{ "shape": ["rectangle"] }
]
I'd like to obtain the following results where keys and their respective values are merged:
[
{ "color": ["red", "blue", "green"] },
{ "shape": ["square", "circle", "rectangle"] }
]
After some research I was thinking of something like this (doesn't work/compile), but I'm missing some pieces:
val colors1 = mapOf("color" to listOf("red", "blue"))
val colors2 = mapOf("color" to listOf("red", "green"))
val shapes1 = mapOf("color" to listOf("square", "circle"))
val shapes2 = mapOf("color" to listOf("rectangle"))
var mainList = mutableListOf(colors1, colors2, shapes1, shapes2)
mainList.reduce { acc, it -> (acc.asSequence() + it.asSequence())
.distinct()
.groupBy({it.key}, {it.value})
.mapValues { (_, values) -> values.flatten().distinct() }
Any help would be greatly appreciated.
Upvotes: 1
Views: 1848
Reputation: 147901
Instead of merging the maps with reduce
, you can use flatMap
with the map entries
. So it should work this way:
mainList
.flatMap { it.entries }
.groupBy({ it.key }, { it.value })
.mapValues { (_, values) -> values.flatten().toSet() }
Also, a little bit more efficient way to flatten the values in the last line is:
.mapValues { (_, values) -> values.flatMapTo(mutableSetOf()) { it } }
This removes the overhead of the intermediate collection that was created to store the values between flatten()
and distinct()
/toSet()
, but still ensures that the items are unique because they are added to a mutableSet()
.
Sample with reassigning the mainList
: (link)
Upvotes: 1