Groovyでは <=>
という演算子が有ります。
この演算子は宇宙船演算子というらしいです(PHP7情報)
やっと名前を知ることが出来たのでじゃあ一体ドコで使うの?というサンプルを投稿します。
まぁタイトルに有るとおりソートで威力を発揮します!
シンプルなサンプルとして、数値が格納されたリストを昇順にソートしてみます。
assert [1,2,3,4,5] == [3,1,5,4,2].sort {left, right -> left <=> right}
GroovyのListのsort
メソッドは、リストの先頭から自動的に1つめと2つ目の値を、渡すクロージャに渡してくれるので、その値に対して例の宇宙船演算子<=>
を指定するだけです。
じゃあ降順は?という話になりますね。はい簡単です。単純に比較順序を逆にするだけです。
assert [5,4,3,2,1] == [3,1,5,4,2].sort {left, right -> right <=> left}
こんな感じで、Groovyではお手軽にリストの中身をソートできます。宇宙船演算子とクロージャのおかげですね!
ただ、コレだけだとググれば山ほど出てくるので、今回は複数のキーをソート対象にしてみます。
条件は、
- リストにクラスAのインスタンスを格納する。
- そのリスト内のAインスタンスをそれぞれ、プロパティaの値で降順でソートする。
- ただし、プロパティaの値が同じ場合は、プロパティbの値で比較して、降順でソートする。
です。
ココで新しいキーワード?:
が出てきます。コレはエルビス演算子
というものです。プレスリー!!
コレは、左辺がtrueなら左辺を、左辺がfalseなら右辺を返すというイカした演算子です。
groovy:000> assert 100 == 0?:100
===> null
groovy:000> assert 100 == 100?:0
===> null
このエルビス演算子を利用すると、NULLチェックをしてNULLなら別の値を入れて。。。というような作業を更にスマートに表現できる可能性が高まります。
Date d = null
println d ?: "oh... Dateがヌルダヨー"
エルビス演算子の詳細はまた別途投稿したいと思います。
では、これらを組み合わせてソートを実装してみます。
class A{
def a
def b
}
assert ["a=2, b=1", "a=1, b=2", "a=1, b=1"] == [
new A(a:1,b:1),
new A(a:1,b:2),
new A(a:2,b:1)
].sort{ l,r ->
r.a<=>l.a ?: r.b<=>l.b
}.collect {"a=${it.a}, b=${it.b}"}
ちょっと見辛いですね。
実行結果としては当然、
a=2, b=1
a=1, b=2
a=1, b=1
という並びになっています。
以上です。