uehaj's blog

Grな日々 - GroovyとかGrailsとかElmとかRustとかHaskellとかReactとかFregeとかJavaとか -

kobo-commonsがお届けする「複数のキーによるソート」

まえに、Groovyのsortにまつわる衝撃の事実という記事で、Groovyには簡単に複数のキーでソートする方法があるとおもってたけど実は存在しなかった、という事を書きました。

複数のキーでのソートとは、例えば"Groovy list.sort by first, second then third elements"で質問されているようなケースです。まあ解決は難しくはないんだけど、ひと手間かかる。

実は、id:nobeansさんが、上の記事の「あると思ってたけど無かった」方法をkobo-commonsライブラリというものの中で一機能として具現化してくれています。
これを使うと、上の質問は

import org.jggug.kobo.commons.lang.CollectionUtils
CollectionUtils.extendMetaClass()
    
list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]
list = list.sort{ [ it[0], it[1], it[2] ]} // 複数のキー(0番目、1番目、2番目の要素)を順に比較してソート。
assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]]
    
list2 = [ [name:"a", age:13], [name:"a",age:15], [name:"b", age:13] ]
list2 = list2.sort{[it.name, it.age] } // 複数のキー(nameキー、ageキー)を順に比較してソート。
assert list2 == [[name:"a", age:13], [name:"a", age:15], [name:"b", age:13]]


のように、第1キー、第二キー・・をリストで返すクロージャをsortに渡してやる事で、ソートできるようになるんですねー。
これってなにげに便利?

kobo-commonsライブラリには、他にもいくつか機能があります。

  • equals()とhashCode()を自動生成する「@Equiv」アノテーション(AST変換)
  • ありそうでなかったString.tr()。
  • Rubyからぱくっちゃえシリーズ: Object.tap()

なかなか渋いです。trはあると便利ですよね。
評判が良ければ本家に取り込んでもらう活動を進めたいと思ってるのですがいかがなものでしょうか。