.groupBy { it.userId }
.mapValues { it.value.maxByOrNull(Item::createdAt)!! }
Ну без !! не получится, потому что нет гарантий, что там есть максимум
Пока, видимо, нет
Но там точно непустые списки
Во-первых компилятор об этом не знает. Во-вторых maxBy может возвращать null на непустом списке. Посмотрите его описание
Не совсем правда, очень даже получится, просто совсем красивых решений из коробки нет. Но можно вынести, если нужно: fun main() { val itemsList = listOf(Item("a"), Item("b")) itemsList .groupingBy { it.userId } .aggregate { key, acc: Item?, curr, first -> if (acc == null) curr else maxOf(acc, curr, compareBy { it.createdAt }) } itemsList.groupingBy { it.userId }.eachMaxBy { it.createdAt } } fun <K, V, R: Comparable<R>> Grouping<V, K>.eachMaxBy(selector: (V) -> R) = aggregate { key, acc: V?, curr, first -> if (acc == null) curr else maxOf(acc, curr, compareBy(selector)) }
Хорошо. Вы просто перехватывайте случай пустого списка раньше. Не уверен, что оно чем-то лучше. Но согласен, что можно придумать решение, если залезть в реализацию.
Так это не я делаю, aggregate в groupingBy знает о том, что списки непустые
Да не может в groupBy быть пустой список
Я не спорю. Но нет способа сообщить об этом тому, кто этот список будет использовать. Поэтому это тот случай, когда !! уместно
Просто проблема, что на Grouping есть два с половиной экстеншна вместо вагона.
Это может быть тот случай, что лекарство вреднее болезни. Grouping вообще довольно эзотерическая штука
Да не особо вреднее, просто удобная объединялка в условно одну операцию цепочек вроде groupBy(...).mapValues(...)
Она сделана для ленивой редукции. Но исползовать ее сложновато
Так ничего сложного, просто там завезли вместо всей портянки экстеншнов только базовые aggregate/fold/reduce и только один конкретный eachCount
Ну я в свое время игрался, как-то оно не очень хорошо ложится
Ну вот вроде с готовыми экстеншнами выглядит норм: itemsList.groupingBy { it.userId }.eachMaxBy { it.createdAt }
Обсуждают сегодня