この記事は、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
を使うやり方など、他にもソートする(微妙に結果が違う)方法があったりするので、もしこのページのコードが用途に合わない場合には検討してみて下さい。
それではまた、他の記事でお会いしましょう!