jetpack compose сводная таблица

Столкнулся с необходимостью реализации функционала "Сводной таблицы" из Microsoft Excel на Jetpack Compose Multiplatform, конкретно под Windows(хоть это и не важно для решения).

Имеющиеся вводные данные: kotlin data class с моделью, заполненной из интерфейса

data class PivotModel(
    val substance: String,
    var toManufacture: Int,
    val onWarehouse: Int
)

Заполняю список и получаю результат в примерно таком цикле forEach, добывая значения из базы данных (условный mainList)

mainList.forEach{
    if (current.substance == mainList.substance) {
        pivotList.add(PivotModel(
            pivot.x, pivot.y, pivot.z))
    }
}

И в результате отображаю данные в текстовом поле

val newList = pivotList.distinct()
Text(text = newList.toString())

Всё хорошо, я получаю данные, которые мне необходимо без дублей. Однако мне необходимо "схлопнуть" одинаковые элементы списка, причём не полностью - а частично, привожу пример далее:

То, что я получаю:

Парацетамол,  10,    115
Ибупрофен,    10,    197
Анальгин,     10,    100
Ромашка,      10,    102
Градусник,    10,    210
Анальгин,     15,    100

После обработки distinct() я получаю только удаление от полных дублей, т.е. два Анальгина / 10,100 будут восприняты как один Анальгин / 10, 100 (полный дубль), а два Анальгина 10, 100 и 15, 100 воспринимаются как разные, потому что модели отличаются. А раз отличается часть модели - вся модель другая.

Мне же необходимо, чтобы первое и последнее значение не менялось никогда, а дубли "схлапывались" по количеству, наподобие 1С или сводных таблиц в вышеупомянутом Excel.

То есть пример того, что мне необходимо получить, должен выглядеть как:

Парацетамол,  10,    115
Ибупрофен,    10,    197
Анальгин,     25,    100
Ромашка,      10,    102
Градусник,    10,    210

Анальгина должно стать 20, вместо двух дублей по 10, которые игнорируются сортировкой вследствие прохода distinct()

distinctBy { it.substance } не помогает, а только выбирает первое предложенное значение из списка, как будто вызывая getFirstOrNull

Есть идеи, но нет решения.

P.S. Не имею отношения к медицине и фармацевтике, просто заполнил пример для стака -_-


Ответы (1 шт):

Автор решения: Eugene Krivenja

Набросал идею группировка + агрегация и потом результат снова в список.

    val pivotList = listOf(
        PivotModel("Парацетамол",  10,    115),
        PivotModel("Ибупрофен",    10,    197),
        PivotModel("Анальгин",     10,    100),
        PivotModel("Ромашка",      10,    102),
        PivotModel("Градусник",    10,    210),
        PivotModel("Анальгин",     15,    100),
    )
    println(pivotList)

    val newList = pivotList.groupingBy { it.substance }.aggregate { key: String, acc: PivotModel?, element: PivotModel, first: Boolean ->
        if (first) {
            element
        } else {
            PivotModel(key, acc!!.toManufacture + element.toManufacture, acc.onWarehouse)
        }
    }.flatMap { listOf(it.value) }
    println(newList)

На выходе

Парацетамол, 10, 115, 
Ибупрофен, 10, 197, 
Анальгин, 25, 100, 
Ромашка, 10, 102, 
Градусник, 10, 210, 
→ Ссылка