Groovyソースコード斜め読み(その1)「Groovyにもタプルがあった 」
このシリーズの一覧はこちら
はじめに
なんと、無いと思っていたタプル(組)がGroovyにもある模様。しかし、実体はListを薄くラッピングしただけのもののよう…せっかく見つけたので一応ご紹介ということで。
(動作確認: Groovy Version: 1.8.0-rc-1 JVM: 1.6.0_22)
クラス階層
java.lang.Object java.util.AbstractCollection<E> java.util.AbstractList groovy.lang.Tuple
リストとして実装されている。
コンストラクタ
Tuple(Object[] contents)
クラスをnewするにはオブジェクト配列を渡せばいいようです。オブジェクト配列ってことは要素は何でもアリということですね。
空タプル
def t1 = new Tuple() assert t1 == [] , '空リストと同じ' assert t1.class.name == 'groovy.lang.Tuple' , '型はTuple型' assert t1.size() == 0 , 'サイズはもちろん0'
intの三つ組み
def t2 = new Tuple(1, 2, 3) assert t2 == [1, 2, 3] , 'intのリスト' assert t2.class.name == 'groovy.lang.Tuple' , '型はTuple型' assert t2.size() == 3 , 'サイズは3'
いろんな要素
def t3 = new Tuple('str', 12.345G, ['a', 'b', 'c'], [m: 'map']) assert t3 == ['str', 12.345G, ['a', 'b', 'c'], [m: 'map']] , 'いろんな要素のリスト' assert t3.class.name == 'groovy.lang.Tuple' , '型はTuple型' assert t3.size() == 4 , 'サイズは4'
値の取り出し
def t4 = new Tuple(10, 20, 'A') assert t4.get(0) == 10 , '#get(index)で値を取得' assert t4[1] == 20 , '#get(index)のシンタクスシュガー' assert t4[3] == null , 'index範囲を超えた場合はnull' assert t4[-1] == 'A' , '単純にリストなのでマイナスインデックスも使えたりする。'
値の取り出しはシンプルに#getメソッドでindexアクセス。
値の代入
def t5 = new Tuple(10, 20) t5[0] = 30 // => java.lang.UnsupportedOperationException
怒られます。値の再代入は許可されないようですね、そうじゃないとタプルじゃないですもんね。
マップのキーとして使ってみる
def doubleKeyMap = [:] doubleKeyMap[new Tuple('a', 'b')] = 'A and B' doubleKeyMap[new Tuple('c', 'd')] = 'C and D' def getValue = { Tuple t -> assert t.size() == 2 doubleKeyMap[t] } assert getValue(new Tuple('a', 'b')) == 'A and B' assert getValue(new Tuple('b', 'a')) == null
使えた。
FizzBuzzもやってみた(似非パターンマッチ)
def fizz = new Tuple(true, false) def buzz = new Tuple(false, true) def fizzbuzz = new Tuple(true, true) def result = (1..100).collect{ new Tuple(new Tuple(it % 3 == 0, it % 5 == 0), it) }.collect { switch (it[0]) { case {it == fizz} : return 'Fizz' case {it == buzz} : return 'Buzz' case {it == fizzbuzz} : return 'FizzBuzz' default : return it[1] } }.join(', ') println result
できた。
値束縛っぽく使ってみる
def (a, _) = new Tuple(10, 20) assert a == 10