2017年06月09日
case classとList, Map変換
shapelessでcase class -> List, Mapへの変換
case class Foo(a: String, b: Int, c: Long)
val foo = Foo("test", 1, 2)
こちらのコードをshapelessを使ってList, Mapへ変換してみます。
※shapelessを簡単にREPLで使うには
curl -s https://raw.githubusercontent.com/milessabin/shapeless/master/scripts/try-shapeless.sh | bash
Listへの変換
Generic
の力を借りてcase class -> HListとすることでListに変換できます。
import shapeless._
import shapeless.ops.hlist.ToTraversable
def caseClassToList[A, R <: HList, V](a: A)(implicit gen: Generic.Aux[A, R], toList: ToTraversable.Aux[R, List, V]): List[Any] = gen.to(a).toList
caseClassToList(foo)
res1: List[Any] = List(test, 1, 2)
Mapへの変換
Mapの場合は、keyの情報が必要になるので LabelledGeneric
を使って変換します。
import shapeless._
import shapeless.ops.record.ToMap
def caseClassToMap[A, R <: HList, K, V](a: A)(implicit gen: LabelledGeneric.Aux[A, R], toMap: ToMap.Aux[R, K, V]): Map[Symbol, Any] = {
toMap(gen.to(a)).map {
case (a: Symbol, b) => (a, b)
}
}
caseClassToMap(foo)
res1: Map[Symbol, Any] = Map('c -> 2, 'b -> 1, 'a -> test)
まとめ
HListに変換することで、任意の型へ変換の非常に便利です。