Как сортировать в порядке убывания, используя несколько полей сравнения в Kotlin

Kotlin позволяет сортировать ASC и массив, используя несколько полей сравнения.

например:

return ArrayList(originalItems)
    .sortedWith(compareBy({ it.localHits }, { it.title }))

но когда я пытаюсь сортировать DESC (compareByDescending()), это не позволяет мне использовать несколько полей сравнения.

есть ли способ я могу сделать это?

4 ответов


можно использовать thenByDescending() (или thenBy() для возрастающего порядка) функция расширения для определения вторичного Comparator.

предполагая, что originalItems из SomeCustomObject, что-то вроде этого должно работать:

return ArrayList(originalItems)
        .sortedWith(compareByDescending<SomeCustomObject> { it.localHits }
                .thenByDescending { it.title })

(конечно, вы должны заменить SomeCustomObject С вашим собственным типом для общего)


вы также можете просто использовать сортировку ASC, а затем отменить его:

return ArrayList(originalItems).sortedWith(compareBy({ it.localHits }, { it.title })).asReversed()

реализация asReversed() вид из отсортированного списка с обратным индексом и имеет лучшую производительность, чем использование reverse()


реверсом компаратор работает:

originalItems.sortedWith(compareBy<Item>({ it.localHits }, { it.title }).reversed())

ArrayList(originalItems)
    .sortedWith(compareByDescending({ it.localHits }, { it.title }))

вам нужно только определить эту функцию:

fun <T> compareByDescending(vararg selectors: (T) -> Comparable<*>?): Comparator<T> {
    return Comparator { b, a -> compareValuesBy(a, b, *selectors) }
}

или вы можете использовать Comparator напрямую:

ArrayList(originalItems)
    .sortedWith(Comparator { b, a -> compareValuesBy(a, b, { it.localHits }, { it.title }) })