I am using sortedBy()
to perform sorting on the collection of objects.
Since the order may change depending on the user choice, I've ended up with the following code
val sortedList = if (sortingOrder == WordSortingOrder.BY_ALPHA) {
list.sortedBy { it.word.value }
} else {
list.sortedBy { it.createdAt }
}
Then I perform further actions on the sorted collection.
I realize that sortedBy()
method expects a property to be returned.
I wonder if there is a way to embed the sorting condition in one chain of collection methods.
If your properties are of different types you won't be able to select one of them based on some condition as a result for sortedBy
, as their common supertype would be inferred as Any
and it is not a subtype of Comparable<R>
as sortedBy
expects.
Instead you can utilize sortedWith
method, which takes a Comparator
, and provide a comparator depending on the condition:
list.sortedWith(
if (sortingOrder == WordSortingOrder.BY_ALPHA)
compareBy { it.word.value }
else
compareBy { it.createdAt }
)
Comparators for different properties are created here with the kotlin.comparisons.compareBy
function.
You can then extract the logic which selects comparator based on sorting order to a function:
list.sortedWith(comparatorFor(sortingOrder))
fun comparatorFor(sortingOrder: WordSortingOrder): Comparator<MyType> = ...
The sortedBy
expects any function of type (T) -> R
as its parameter. A property is a corner case of that.
Which means you can do this:
val sortedList = list
.sortedBy { if (sortingOrder == WordSortingOrder.BY_ALPHA) it.word.value else it.createdAt}
Or, if you need something more OOP-ish:
enum class WordSortingOrder(val transform: (MyObject) -> Int) {
BY_ALPHA({it.word.value}),
BY_ALPHA_REVERSED({-1 * it.word.value}),
DEFAULT({it.createdAt})
}
val sortedList = list.sortedBy { sortingOrder.transform(it)}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With