Слияние списка карт (списка строк) - PullRequest
1 голос
/ 31 мая 2019

Малыш Котлин Дев тут:)

Учитывая следующую структуру:

[
  { "color": ["red", "blue"] },
  { "color": ["red", "green"] },
  { "shape": ["square", "circle"] },
  { "shape": ["rectangle"] }
]

Я хотел бы получить следующие результаты, где ключи и их соответствующие значения объединены:

[
  { "color": ["red", "blue", "green"] },
  { "shape": ["square", "circle", "rectangle"] }
]

После некоторого исследования я думал о чем-то вроде этого (не работает / не компилируется), но мне не хватает некоторых частей:

val colors1 = mapOf("color" to listOf("red", "blue"))
val colors2 = mapOf("color" to listOf("red", "green"))
val shapes1 = mapOf("color" to listOf("square", "circle"))
val shapes2 = mapOf("color" to listOf("rectangle"))
var mainList = mutableListOf(colors1, colors2, shapes1, shapes2)

mainList.reduce { acc, it -> (acc.asSequence() + it.asSequence())
    .distinct()
    .groupBy({it.key}, {it.value})
    .mapValues { (_, values) -> values.flatten().distinct() }

Любая помощь будет принята с благодарностью.

1 Ответ

1 голос
/ 31 мая 2019

Вместо объединения карт с reduce вы можете использовать flatMap с картой entries. Так должно работать так:

mainList
    .flatMap { it.entries }
    .groupBy({ it.key }, { it.value })
    .mapValues { (_, values) -> values.flatten().toSet() }

(работающий образец)

Кроме того, более эффективный способ выравнивания значений в последней строке:

    .mapValues { (_, values) -> values.flatMapTo(mutableSetOf()) { it } }

Это устраняет накладные расходы промежуточной коллекции, которая была создана для хранения значений между flatten() и distinct() / toSet(), но при этом гарантирует, что элементы являются уникальными, поскольку они добавляются в mutableSet().


Образец с переназначением mainList: (ссылка)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...