web-dev-qa-db-ja.com

Kotlin-フォーマットされた日付文字列を使用してリストを並べ替える(機能)

Kotlin REST APIを作成しようとしています。これは、PostgreSQLデータベースから値を取得します。これらの結果の値は次のようになります。"14-10-2016 | 15:48"および"01-08-2015 | 09:29"したがって、構文は基本的にdd-MM-yyyy | hh:mm

今私がやろうとしているのは、配置された日付でそれらを並べ替える関数を作成することです。 (これらの文字列が配列内にあると想定します)

var list = listOf("14-10-2016 | 15:48",
                  "01-08-2015 | 09:29",
                  "15-11-2016 | 19:43")

これらをソートする最もクリーンな(そして最も機能的な)方法は何でしょうか? (つまり、日、月などの部分文字列を取得してIntにキャストし、ネストされたループで比較して、結果を別の配列に書き込む必要がない方法はありますか? (それが私が考えることができる唯一の方法です)。

7
Ivar Reukers

複数のアプローチを使用できます。ソートされた結果を取得した後の処理方法によって異なります。

注意点:

  • Java.time.LocalDateTimeはすでにJava.lang.Comparable<T>インターフェースを実装しています。 kotlin stdlib List.sortByを使用して、List<LocalDateTime>を直接ソートできます。

参照:

// 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>

最も簡単な方法は、String -> Java.time.LocalDateTimeを変換し、List.sortByを直接使用することです。

全体の実装は次のようになります。

 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)

org.joda.time.DateTimeを使用したい場合は、変換関数に小さな変更を加えるだけです。

フレンドリーなリマインダーです。Kotlinでの最初の選択肢として常にvalを選択してください:)。

8
Gary LO

優れたサラバナの答えの別の選択肢(私のようなミニマリストでコンパクトなフリークのために..)は次のとおりです。

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は単一入力のデフォルト変数です

1
elect

DateTimeFormatterを使用して解析し、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);

出力

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

更新

LocalDateTimeだけでComparatorに変換できます

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

出力

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