Hi! I have a List of objects, and depending on a f...
# getting-started
s
Hi! I have a List of objects, and depending on a flag, I need to sort this ascending or descending by a field. How can I best accomplish this?
j
Copy code
val maybeSortedList = if (flag) list.sortedBy { it.prop } else list sortedDescendingBy { it.prop }
s
i was hoping there'd be a one liner. oh well
j
It can be on one line :)
You can make an extension as well
👍 1
e
not quite one-liners but
Copy code
val ascList = list.sortedBy { it.prop }
val sortedList = if (asc) ascList else ascList.asReversed()
Copy code
val comparator = compareBy(T::prop)
val sortedList = list.sortedWith(if (asc) comparator else comparator.reversed())
n
How about
Copy code
fun <T, R: Comparable<R>> List<T>.sortedBy(descending: Boolean = false, selector: (T) -> R?): List<T> {
    return if (descending) sortedByDescending(selector) else sortedBy(selector)
}
listOf(3, 1, 4).sortedBy(true) { it }
4, 3, 1
l
You could also set an integer value to 1 or -1 depending on whether you want it ascending or descending, then multiply the result of the
compareTo
function by this value. This allows you to avoid an
if
statement in the comparator which is faster (if you care about that).
j
This is an option, but that only works if the type of the comparable field is numeric. Also, there is no
if
statement in the comparator in the above approaches. The
if
only runs once, and then all elements are processed, just like the
if
that would set the 1 / -1 value. The -1 approach also add a multiplication for each element, if we're splitting hair. But anyway these considerations are most likely pointless.
l
The
compareTo
method always returns an integer when comparing two objects. regardless of type.
j
Ah my bad, I read too quickly, I thought you meant to multiply in the
sortedBy
function, not
compareTo
e
multiply by -1 doesn't work if the comparator returns
Int.MIN_VALUE
j
And if you're using
compareTo
by hand I fail to see how this would be an improvement in terms of conciseness/ style
l
@ephemient that's actually a pretty astute observation. I was going to say "that'll never happen" (and it doesn't in the cases where I use it, at least in my current project, I just checked), but it is indeed a valid point.