Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin groupby value as set instead of list

Tags:

kotlin

I'm going to groupby Set<Pair<String,Int>> values to Map<String, Set<Int>> so simply. Find all matching ints for string and create set. I've got solution that works:


setStringInt.stream()
            .collect(
                groupingBy(
                    Projection::stringObj,
                    mapping(Projection::intObj,
                        toSet<Int>())
                )
            )

I've got kind of cleaner:

            .groupBy { it.stringobj }
            .mapValues { it.value.map { it.intobj }.toSet() }

But it's looking quite dirty. Do you have any idea how to simplify this? Am I able to do this without using stream?

like image 620
MrNetroful Avatar asked Mar 16 '19 10:03

MrNetroful


2 Answers

I think this is more readable:

setStringInt.groupBy({ it.first }, { it.second }).mapValues { it.value.toSet() }

using the

inline fun <T, K, V> Iterable<T>.groupBy(
    keySelector: (T) -> K,
    valueTransform: (T) -> V
): Map<K, List<V>>

overload.

like image 160
Alexey Romanov Avatar answered Oct 18 '22 18:10

Alexey Romanov


You can just use the Kotlin functions groupBy and then mapValues directly on the Set.

You first use groupBy on it.first to get a Map<String, List<Pair<String, Int>>. Then you need to map the values of the resulting map, so you get a List<Int> from the List<Pair<String, Int>>. Like this:

setStringInt.groupBy { it.first }
            .mapValues { entry -> entry.value.map { it.second }.toSet() }
like image 33
marstran Avatar answered Oct 18 '22 18:10

marstran