Search code examples
kotlinhashmap

Transform a <string, List<string>> map to change values to be as keys


I have a following map, which contains basket number to list of fruits in that basket.

val basketMap = mapOf("basket1" to listOf("apples", "oranges", "grapes"),
                      "basket2" to listOf("oranges", "kiwi", "pineapple"),
                      "basket3" to listOf("grapes", "apples", "strawberry"))

I want to convert this map to fruit to list of baskets that fruit is present in Ex:

val finalExpectedResult = mapOf("apples" to listOf("basket1", "basket3"),
                                "oranges" to listOf("basket1", "basket2"),
                                "grapes" to listOf("basket1", "basket3"),
                                "kiwi" to listOf("basket2"),
                                "pineapple" to listOf("basket2")
                                "strawberry" to listOf("basket3"))

How do I achieve the finalExpectedResult map from the above basketMap in kotlin


Solution

  • First, flatten the map into a list of pairs (basket, fruit), then group again:

    basketMap.flatMap { (k, v) -> v.map { k to it } }
        .groupBy({ it.second }, { it.first })
    

    If our collections are big, we can use sequences instead:

    basketMap.asSequence()
        .flatMap { (k, v) -> v.asSequence().map { k to it } }
        .groupBy({ it.second }, { it.first })
    

    This way we avoid creating a huge list of items and instead, we build a map while iterating over the source map.