Reputation: 2095
Assume I have a
class Question(val tags:List<String>, val text:String)
which (obviously) has multiple tags in addition to other attributes.
I want to convert a number of Question instances to a (single!) tag to Question map such as: Map<String,List<Question>>
.
How do I do that? A simple groupBy { it.tags }
provides a Map<List<String>,List<Question>>
Upvotes: 1
Views: 1050
Reputation: 604
A generic extension function for this, as I've required it a few times:
fun <T, K> Iterable<T>.groupByMany(
keyExtractor: (T) -> Iterable<K>
): Map<K, List<T>> = mutableMapOf<K, MutableList<T>>()
.also { grouping ->
forEach { item ->
keyExtractor(item).forEach { key ->
grouping.computeIfAbsent(key) { mutableListOf() }.add(item)
}
}
}
Usage:
val byTag = questions.groupByMany { it.tags }
Upvotes: 1
Reputation: 3890
val questions: Iterable<Question> = ....
val map = HashMap<String, MutableList<Question>>()
questions.forEach { question ->
question.tags.forEach { tag ->
val otherQuestions = map[tag]
if (otherQuestions == null) map[tag] = arrayListOf(question)
else otherQuestions.add(question)
}
}
val resultMap: Map<String, List<Question>> = map
Upvotes: 0