2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Boolean クラスは、Comparable インターフェイスを実装しているため、
大小比較をすることができます。
truefalse のどちらが大きいかは、API ドキュメントや言語仕様書にも記載されていないようですが、
false < true です(Java の Boolean クラスと同じです。Java の API ドキュメントには記載されています)。

そのため Boolean 値のコレクションをソートすると
false が前(インデックスが小さい方)
true が後ろ(インデックスが大きい方)
に来ます。

listOf(true, false, true, false)
    .sorted()
    .also { println(it) } // > [false, false, true, true]

ただしこれは直観的とは言いがたいので、
少なくともコメントを付けておいた方がよいでしょう。

listOf(true, false, true, false)
    .sorted() // false が前(インデックスが小さい方)に来る
    .also { println(it) } // > [false, false, true, true]

コメントなしでも直感的に分かるようにする

次のような、Comparator<Boolean> オブジェクトを返す関数1を用意しておいて

/** `false < true` であるとする [Comparator] を返す。 */
fun falsesFirst(): Comparator<Boolean> = compareBy { it }

/** `true < false` であるとする [Comparator] を返す。 */
fun falsesLast(): Comparator<Boolean> = compareByDescending { it }

/** `true < false` であるとする [Comparator] を返す。 */
fun truesFirst(): Comparator<Boolean> = compareByDescending { it }

/** `false < true` であるとする [Comparator] を返す。 */
fun truesLast(): Comparator<Boolean> = compareBy { it }

次のように使えば、
コメントを付けなくても直観的に分かるようにできます。

listOf(true, false, true, false)
    .sortedWith(falsesFirst())
    .also { println(it) } // > [false, false, true, true]

listOf(true, false, true, false)
    .sortedWith(falsesLast())
    .also { println(it) } // > [true, true, false, false]

listOf(true, false, true, false)
    .sortedWith(truesFirst())
    .also { println(it) } // > [true, true, false, false]

listOf(true, false, true, false)
    .sortedWith(truesLast())
    .also { println(it) } // > [false, false, true, true]

現実的な使い方

実際には、Boolean そのもののコレクションをソートすることはまずなく、
各要素のプロパティなどから計算した Boolean 型の値に応じてソートすることになるでしょう。
その場合は例えば次のようになります。

data class MyClass(
    val value: Boolean
)


listOf(MyClass(true), MyClass(false), MyClass(true), MyClass(false))
    .sortedWith(
        compareBy(falsesFirst()) { it.value }
    )
    .also { println(it) } // > [MyClass(value=false), MyClass(value=false), MyClass(value=true), MyClass(value=true)]

listOf(MyClass(true), MyClass(false), MyClass(true), MyClass(false))
    .sortedWith(
        compareBy(falsesLast()) { it.value }
    )
    .also { println(it) } // > [MyClass(value=true), MyClass(value=true), MyClass(value=false), MyClass(value=false)]

listOf(MyClass(true), MyClass(false), MyClass(true), MyClass(false))
    .sortedWith(
        compareBy(truesFirst()) { it.value }
    )
    .also { println(it) } // > [MyClass(value=true), MyClass(value=true), MyClass(value=false), MyClass(value=false)]

listOf(MyClass(true), MyClass(false), MyClass(true), MyClass(false))
    .sortedWith(
        compareBy(truesLast()) { it.value }
    )
    .also { println(it) } // > [MyClass(value=false), MyClass(value=false), MyClass(value=true), MyClass(value=true)]

/以上

  1. 関数名は nullsFirst, nullsLast に倣いました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?