Kotlin: сгруппировать и преобразовать в другой объект

#kotlin

#kotlin

Вопрос:

У меня есть список объектов

 data class OldFormat(ShiftId: Int, NozzleValue: Int, NozzleId: Int , UserId: Int)
  

который я хочу сгруппировать по двум полям «shiftId и userId», а затем вычесть максимальное значение каждой группы из минимального значения той же группы, а затем
суммируйте результат, а затем преобразуйте его в новый объект с этим классом:

 data class NewFormat(ShiftId: Int, NozzleValue: Int, UserId: Int)
  

Процесс будет выглядеть следующим образом:

 listOfOldFormat -> groupby(shiftId, userId) -> sum(maximumValue-minimumValue) -> listOfNewFormat
  

Ответ №1:

У нас действительно есть groupBy функция, так что у нас есть все, что нам нужно.

Я не уверен, что вы подразумеваете под subtract the maximum value of each group from the minimum value of the same group and then sum the result (что я должен суммировать?), Поэтому я сделал это как group.value.max - group.value.min и это nozzeValue для NewFormat .

Фрагмент кода:

 data class OldFormat(val shiftId: Int, val nozzleValue: Int, val nozzleId: Int, val userId: Int)
data class NewFormat(val shiftId: Int, val nozzleValue: Int, val userId: Int)

fun main() {

    val old = listOf(
            OldFormat(0, 10, 10, 0),
            OldFormat(0, 120, 10, 1),
            OldFormat(1, 11, 8, 10),
            OldFormat(0, 10, 1, 1),
            OldFormat(1, 50, 10, 10)
    ) // Example data

    old.groupBy {
        it.shiftId to it.userId // After it we have Map<Key, List<OldFormat>>, where key is pair of shiftId and userId
    }.map { entry ->
        val max = entry.value.maxBy { it.nozzleValue }?.nozzleValue ?: 0
        val min = entry.value.minBy { it.nozzleValue }?.nozzleValue ?: 0

        entry.key to (max - min) // Just do whatever you want with that data
    }.map {
        NewFormat(
                shiftId = it.first.first,
                userId = it.first.second,
                nozzleValue = it.second
        ) // And now map it into type you want
    }.let {
        println(it) // Just for seeing result
    }
}
  

Комментарии:

1. Большое спасибо, я попробовал ваш код, он работает до сопоставления с NewFormat, но ключевое слово «it» не работает внутри объекта NewFormat

2. Мне нужно поместить сумму (max — min) в nozzleValue объекта NewFormat

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

4. Извините, я имею в виду сумму (max — min) всех групп

5. Ваш образец можно упростить до old.groupBy({ it.shiftId to it.userId }, OldFormat::nozzleValue).map { (keyPair, values) -> NewFormat(keyPair.first, values.max()!! - values.min()!!, keyPair.second) }