Kotlin - Sort List by using formatted date string (functional)
Solution 1
More than one approach can be used. It depends on how you process after you get the sorted result.
Points to note:
-
java.time.LocalDateTime
has already implementedjava.lang.Comparable<T>
Interface. We can use the kotlin stdlibList.sortBy
to sort theList<LocalDateTime>
directly.
Ref:
// https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sorted-by.html
fun <T, R : Comparable<R>> Iterable<T>.sortedBy(
selector: (T) -> R?
): List<T>
The easiest way is to transform the String -> java.time.LocalDateTime
and use the List.sortBy
directly.
The whole implementation could be like this:
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
...
// Create a convert function, String -> LocalDateTime
val dateTimeStrToLocalDateTime: (String) -> LocalDateTime = {
LocalDateTime.parse(it, DateTimeFormatter.ofPattern("dd-MM-yyyy | HH:mm"))
}
val list = listOf("14-10-2016 | 15:48",
"01-08-2015 | 09:29",
"15-11-2016 | 19:43")
// You will get List<LocalDateTime> sorted in ascending order
list.map(dateTimeStrToLocalDateTime).sorted()
// You will get List<LocalDateTime> sorted in descending order
list.map(dateTimeStrToLocalDateTime).sortedDescending()
// You will get List<String> which is sorted in ascending order
list.sortedBy(dateTimeStrToLocalDateTime)
// You will get List<String> which is sorted in descending order
list.sortedByDescending(dateTimeStrToLocalDateTime)
If you want to use org.joda.time.DateTime
, you can just make a tiny change on the convert function.
A friendly reminder, always pick val
as your first choice in Kotlin :).
Solution 2
Another alternative to the excellent Saravana answer (for minimalist and compact freaks like me..) is:
val cmp = compareBy<String> { LocalDateTime.parse(it, DateTimeFormatter.ofPattern("dd-MM-yyyy | HH:mm")) }
list.sortedWith(cmp).forEach(::println)
01-08-2015 | 09:29
14-10-2016 | 15:48
15-11-2016 | 19:43
Ps: it
is the default variable for single inputs
Related videos on Youtube
Comments
-
Ivar Reukers almost 2 years
I'm trying to create a Kotlin REST API, which retrieves values from a PostgreSQL database. Now the values in these results are f.e.
"14-10-2016 | 15:48"
and"01-08-2015 | 09:29"
So the syntax basically isdd-MM-yyyy | hh:mm
Now what I'm trying to do is create a function that will order them by date placed. (Assume these strings are in an array)
var list = listOf("14-10-2016 | 15:48", "01-08-2015 | 09:29", "15-11-2016 | 19:43")
What would be the cleanest (and most functional) way of sorting these? (so f.e. is there a way where I don't have to take substrings of the day, month, etc. cast them to an
Int
, compare them in a nested loop and write the results to a different array? (that's the only way I could think of). -
Egor over 7 yearsNot sure Kotlin is compatible with Java 8, but anyway, I guess the OP was looking for a solution written in Kotlin.
-
Jayson Minard over 7 yearsinstead of using
map
to print, maybe uselist.sortedWith(cmp).forEach(::println)
-
Saravana over 7 years@Egor sorry, I know Java only but the logic would be similar to the answer I posted
-
Gary LO over 7 years@elect Immutable objects are always easier to trace and can be used in mutli-threaded environment without any worries. Most of the time you won't need
var
in Kotlin if you are familiar with functional approach. Butvar
is more memory efficient, use it wisely to take the only benefit. -
karthik prasad about 6 yearsCall requires API level 26 though. Any backward compatible solutions?