Thomas Auinger
Thomas Auinger

Reputation: 2095

Group by list of keys (Kotlin)

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

Answers (2)

Mike Rippon
Mike Rippon

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

ardenit
ardenit

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

Related Questions