Kotlin - Sort list using formatted date string (functional)

I am trying to create a Kotlin REST API that retrieves values โ€‹โ€‹from a PostgreSQL database. Now the values โ€‹โ€‹in these results are equal to fe "14-10-2016 | 15:48" and "01-08-2015 | 09:29" Thus, the syntax is basically dd-MM-yyyy | hh:mm dd-MM-yyyy | hh:mm

Now what I'm trying to do is create a function that will sort them by date. (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 will be the cleanest (and most functional) way to sort them? (so fe there is a way when I don't need to take the substrings of the day, month, etc., throw them into Int , compare them in a nested loop and write the results to another array? (which is the only way I could think of) .

+5
source share
3 answers

You can use more than one approach. It depends on how you process after getting the sorted result.

Note:

  • java.time.LocalDateTime already implemented by java.lang.Comparable<T> Interface. We can use kotlin stdlib List.sortBy to sort List<LocalDateTime> directly.

Link:

 // 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 convert String -> java.time.LocalDateTime and use 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 small change to the conversion function.

Friendly reminder, always choose val as your first choice in Kotlin :).

+4
source

Another alternative to Saravan's excellent answer (for minimalists and compact freaks like me ..):

 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 individual inputs

+1
source

You can use DateTimeFormatter for parsing and then compare with LocalDateTime

  List<String> dates = Arrays.asList("14-10-2016 | 15:48", "01-08-2015 | 09:29", "15-11-2016 | 19:43"); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy | HH:mm"); List<LocalDateTime> dateTimes = dates.stream().map(date -> LocalDateTime.parse(date, formatter)).sorted().collect(Collectors.toList()); System.out.println(dateTimes); 

Output

 [2015-08-01T09:29, 2016-10-14T15:48, 2016-11-15T19:43] 

Update

You can just convert to LocalDateTime only in Comparator

 List<String> sortedDates = dates.stream().sorted(Comparator.comparing(date -> LocalDateTime.parse(date, formatter))).collect(Collectors.toList()); 

Output

 [01-08-2015 | 09:29, 14-10-2016 | 15:48, 15-11-2016 | 19:43] 
0
source

Source: https://habr.com/ru/post/1258214/


All Articles