Как сортировать в порядке убывания, используя несколько полей сравнения в 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 }) })