Сгруппировать список по значению списка дочерних элементов в kotlin

#kotlin

#kotlin

Вопрос:

У меня есть 2 класса данных

 data class Channel (
        var ID : Int = 0,
        var ParametersList: List<Parameters>? = null
)

data class Parameters (
        var ParamKey : String = "",
        var ParamValue: String = ""
)
  

У меня есть список, созданный из класса Channel

 var channelList = mutableListOf<Channel>(
        Channel(0, mutableListOf<Parameters>(Parameters("SensorGroup","ABCD"),Parameters("Mode","1"))),
        Channel(1, mutableListOf<Parameters>(Parameters("SensorGroup","ABC"),Parameters("Mode","1"))),
        Channel(2, mutableListOf<Parameters>(Parameters("SensorGroup","ABCD"),Parameters("Mode","1")))
)
  

Мне нужно сгруппировать каналы, где ParamKey — это «Группа датчиков», а значения параметров одинаковы

конечный результат должен быть похож

 0=[Channel(ID=0, ParametersList=[Parameters(ParamKey=SensorGroup, ParamValue=ABCD), Parameters(ParamKey=Mode, ParamValue=1)]), Channel(ID=0, ParametersList=[Parameters(ParamKey=SensorGroup, ParamValue=ABCD), Parameters(ParamKey=Mode, ParamValue=1)])]

1=[Channel(ID=1, ParametersList=[Parameters(ParamKey=SensorGroup, ParamValue=ABC), Parameters(ParamKey=Mode, ParamValue=1)])]
  

Я попробовал вложенную группу по, и фильтр не смог достичь какого-либо значимого результата

Ответ №1:

Вы можете использовать groupBy . Выберите ключи, сначала найдя параметры с помощью соответствующего ParamKey. Поскольку они обнуляемы, лямбда-выражение может возвращать значение null, поэтому оно сгруппирует все недопустимые элементы вместе.

Результатом является a Map<String, Channel> , где ключи map являются уникальными ParamValue значениями. Если вам не нужна карта, вы можете просто получить ее values свойство.

 val result = 
  channelList.groupBy { channel -> channel.ParametersList?.firstOrNull { it.ParamKey == "SensorGroup" }?.ParamValue }
  

Кстати, соглашение Kotlin заключается в использовании строчных первых букв для имен свойств и переменных (чтобы их было легко отличить от имен классов и объектов).

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

1. Спасибо за хорошо объясненный ответ. Я пытался выполнить цикл по списку параметров без использования firstOrNull, что усложнило ситуацию.

Ответ №2:

 fun groupByParamKey(key: String) {
    val group = channelList.groupBy { it ->
        it.ParametersList?.first { it.ParamKey == key }?.ParamValue

    }
    print(group)
}

fun main(args: Array<String>) {
    groupByParamKey("SensorGroup")
}