groovy.util.MapEntry
Hash from two arrays - Rosetta Code から
Groovy
keys = ['a','b','c'] vals = ['aaa', 'bbb', 'ccc'] hash = [:] keys.eachWithIndex { key, i -> hash[key] = vals[i] }
Haskell
import Data.Map makeMap ks vs = fromList $ zip ks vs mymap = makeMap ['a','b','c'] [1,2,3]
Groovy は変数を使っているので、Haskell のやり方を Groovy で実装することにする。
Java では Map.Entry は public だが各 Map の Entry の実装クラスは public ではない。
Groovy では Map に entry のみを追加する API があり、Map.Entry が必要なときは groovy.util.MapEntry が使える。
assert hash == [:].putAll([keys, vals].transpose().collect { k, v -> new MapEntry(k,v) }) assert hash == [:] + [keys, vals].transpose().collect { k, v -> new MapEntry(k,v) } assert hash == [:] + [keys, vals].transpose().collect { it as MapEntry } assert hash == [:] + [keys, vals].transpose()*.asType(MapEntry)
- putAll から + に変更してみる
- リストは key, value のペアでコンストラクタ引数と同じ順序なので as で強制型変換できる
- クロージャ内の処理が特にないので展開ドット演算子に変更してみる
2011-05-27 追記
Groovy 1.8 で List#toSpreadMap が追加されていた。
SpreadMap を使っている人がいるんだろうか?
assert hash == [keys, vals].transpose().flatten().toSpreadMap().@mapData
2011-05-31 追記
Groovy 1.7.9 で追加された Collection#collectEntries が Hash from two arrays のための API のようだ。
assert hash == [keys, vals].transpose().collectEntries { it }