Thursday, April 12, 2018 / Groovy

Haskell の zip に相当する groovy の transpose が便利

2つのリストをつなぎ合わせたリストをつくる Haskell の zip 相当の機能は、Groovy では transpose で実現できます。

具体例、たとえば本名から別名を探し出す場合に使う

以下のような 本名のリストと、対応する別名のリストがあったとする

def 本名 = '岡部倫太郎 椎名まゆり 橋田至'.split(/ /)
def 別名 = '鳳凰院凶真 まゆしぃ ダル'.split(/ /)

本名 と 別名 の対比リストを出すには…

[本名, 別名].transpose().each { a,b->
    println "$a -> $b"
}

本名から 別名を引くには…

def who = '岡部'
def result =  [本名, 別名].transpose().find( { a,b-> a.contains(who) } )

結果の result には [本名,別名] の配列が入ります。

従って、別名を表示したければ、 result[1] とすればよい。

まとめると

def 本名 = '岡部倫太郎 椎名まゆり 橋田至'.split(/ /)
def 別名 = '鳳凰院凶真 まゆしぃ ダル'.split(/ /)

// 本名 と 別名 の対比リストを出す
[本名, 別名].transpose().each { a,b->
    println "$a -> $b"
}

// 本名から 別名を引く
def who = '岡部'
def result =  [本名, 別名].transpose().find( { a,b-> a.contains(who) } )

//println result // [岡部倫太郎, 鳳凰院凶真]
println result[1]

これは2つのリストではなく、3つのリストを zip することもできる。

def 本名 = '岡部倫太郎 椎名まゆり 橋田至'.split(/ /)
def 別名 = '鳳凰院凶真 まゆしぃ ダル'.split(/ /)
def 別名2= 'オカリン まゆしぃ スーパーハカー'.split(/ /)

[本名, 別名].transpose().each { a,b,c->
    println "$a -> $b, $c"
}

// 本名から 別名,別名2を引く
def who = '岡部'
def result =  [本名, 別名, 別名2].transpose().find( { a,b,c-> a.contains(who) } )

println result // [岡部倫太郎, 鳳凰院凶真, オカリン]

Groovy便利。