Kotlin

null を含むリストのソート(昇順/降順)[Kotlin]

この記事は、Kotlinでnullを含むリストをソートする方法を紹介します。

nullが含まれるコレクションのソート処理では、nullを先頭にするか最後尾にするかで、処理をカスタマイズしなければなりません。

私自身も書き方を忘れることが多いので、すぐに参照できるように記事として残すことにしました。

ちょっとした小ネタですが、良かったら参考にしてみて下さい。

サンプルコード

整数をソートするパターン

fun sortSample() {
    val list = listOf(5, null, 2, 4, 3, 1)

    // nullを先頭にして、昇順でソート
    val naturalOrder = list.sortedWith(nullsFirst())
    println(naturalOrder)

    // nullを最後尾にして、降順でソート
    val reverseOrder = list.sortedWith(nullsLast(reverseOrder()))
    println(reverseOrder)
}

出力結果

[null, 1, 2, 3, 4, 5]
[5, 4, 3, 2, 1, null]

オブジェクトをソートするパターン

data class Data(val id: Int, val order: Int?)

fun sortSample2() {
    val list = listOf(
        Data(1, 5),
        Data(2, null),
        Data(3, 2),
        Data(4, 4),
        Data(5, null),
        Data(6, 3),
        Data(7, null),
        Data(8, 1)
    )

    // nullを先頭にして、昇順でソート
    val naturalOrder = list.sortedWith(compareBy(nullsFirst()) { it.order })
    println(naturalOrder)

    // nullを最後尾にして、降順でソート
    val reverseOrder = list.sortedWith(compareBy(nullsLast(reverseOrder())) { it.order })
    println(reverseOrder)
}

出力結果

[Data(id=2, order=null), Data(id=5, order=null), Data(id=7, order=null), Data(id=8, order=1), Data(id=3, order=2), Data(id=6, order=3), Data(id=4, order=4), Data(id=1, order=5)]
[Data(id=1, order=5), Data(id=4, order=4), Data(id=6, order=3), Data(id=3, order=2), Data(id=8, order=1), Data(id=2, order=null), Data(id=5, order=null), Data(id=7, order=null)]

KotlinのsortedWithはドキュメントにもあるように、安定ソートなのでnullの要素が複数ある場合でも、ソート前の順序関係が維持されます。

まとめ

最後に、この記事の内容をまとめます。

要点

  • sortedWith / nullsFirst / nullsLast / reverseOrder を組み合わせてソートを行う
  • 独自オブジェクトなどのソートを行う場合は、compareBy を使う
  • 安定ソートなので null 同士の順序が入れ替わらない

ソート処理はどの言語でも必要になるものの、書き方が大きく異なることが多いので、プログラミング言語ごとに覚えるのが大変だと思います。

Kotlinのソート処理はシンプルで、キレイな書き方が出来るので、すごく気に入っています。

このページで紹介した方法以外にも、compareByDescending を使うやり方など、他にもソートする(微妙に結果が違う)方法があったりするので、もしこのページのコードが用途に合わない場合には検討してみて下さい。

それではまた、他の記事でお会いしましょう!

この記事は役に立ちましたか?

  • この記事を書いた人
アバター画像

ゴイチ

ソフトウェアエンジニア歴20年。 C/C++, C#, Java, Kotlinが得意で、組込系・スマホ・大規模なWebサービスなど幅広いプログラミング経験があります。 現在は某SNSの会社でWebエンジニアをしています。

-Kotlin
-