Reputation: 23
We want to sort objects by three different criteria, the criteria with higher priority overrides the next one):
example:
sorted:
we return the list the following way:
list.sortedWith(statusComparator.thenBy { it.sort }
What is missing is the sorting of items with time = null. How do I sort the items with time = null to the top and leave the remaining sorting untouched?
Upvotes: 2
Views: 1158
Reputation: 28470
To sort depending if the value is null we can... do exactly this, sort by checking if it is null:
list.sortedWith(
statusComparator
.thenBy { it.time != null }
.thenBy { it.sort }
)
It works, because false
is considered smaller than true
. And it returns true
for any non-null value, so all non-null values are considered the same.
We can join time
and sort
steps into a single one, by returning null if time
is null and sort
otherwise:
.thenBy { item -> item.time?.let { item.sort } }
// or:
.thenBy { if (it.time == null) null else it.sort }
It could be a little more performant, but I consider this harder to understand and less flexible.
Upvotes: 5
Reputation: 23357
You can combine Comparator
objects with thenComparing
so you probably want to write a comparator for the time something like
val timeComparator = Comparator<YourObject> { first, second ->
when {
first.time == null && second.time != null -> -1
first.time == null && second.time == null -> 0
first.time != null && second.time == null -> 1
else -> 0
}
}
And then change
list.sortedWith(statusComparator.thenBy { it.sort }
to
list.sortedWith(statusComparator.thenComparing(timeComparator).thenBy { it.sort })
Upvotes: 2