Reputation: 69
As I mentioned in the title. I would like to group List of Pairs by the second value. I came up with a code below that works fine, but I'm wondering if there is a possibility to do it more elegant using lambdas.
val data = mapOf(
Pair("a1", listOf("b1", "b2", "b3", "b4", "b5")),
Pair("a2", listOf("b1", "b7", "b8", "b9", "b10")),
Pair("a3", listOf("b6", "b7", "b8", "b9", "b10")),
Pair("a4", listOf("b6", "b7", "b8", "b9", "b11")),
Pair("a5", listOf("b6", "b2", "b12", "b9", "b13"))
)
val map = mutableMapOf<String, MutableList<String>>()
data.forEach { (k, v) ->
v.forEach {
if (map.containsKey(it)) {
map[it]?.add(k)
} else {
map[it] = mutableListOf(k)
}
}
}
Upvotes: 1
Views: 851
Reputation: 81997
According to your given example, the expected result is
{b1=[a1, a2], b2=[a1, a5], b3=[a1], b4=[a1], b5=[a1], b7=[a2, a3, a4], b8=[a2, a3, a4], b9=[a2, a3, a4, a5], b10=[a2, a3], b6=[a3, a4, a5], b11=[a4], b12=[a5], b13=[a5]}
You could expand the given data structure in a way that every element from your second element is being associated to the first element. But be aware that this results in additional space. Grouping becomes easier then:
data.entries
.flatMap { (k, v) -> v.map { k to it } }
.groupBy(keySelector = Pair<*, *>::second, valueTransform = Pair<*, *>::first) //group by list element, only add key to group
The iterative approach can be simplified to:
val map = mutableMapOf<String, List<String>>().withDefault { listOf() }
for ((k, v) in data) {
for (e in v) map[e] = map.getValue(e) + k
}
Upvotes: 1