Сгруппируйте пары по второму значению и отобразите его там, где ключом является второй элемент, а значением является список первых элементов, связанных со вторым - PullRequest
0 голосов
/ 26 июня 2019

Как я уже упоминал в названии.Я хотел бы сгруппировать список пар по второму значению.Я придумал приведенный ниже код, который прекрасно работает, но мне интересно, есть ли возможность сделать это более элегантно, используя лямбды.

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)
        }
    }
}

1 Ответ

1 голос
/ 26 июня 2019

Согласно вашему приведенному примеру, ожидаемый результат

{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 = [а5]}

Вы можете расширить данную структуру данных таким образом, чтобы каждый элемент из вашего второго элемента был связан с первым элементом. Но имейте в виду, что это приводит к дополнительному пространству. Группировка становится проще:

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

Итерационный подход может быть упрощен до:

val map = mutableMapOf<String, List<String>>().withDefault { listOf() }

for ((k, v) in data) {
    for (e in v) map[e] = map.getValue(e) + k
}
...