将[String,Object]从DB(或键值存储)映射到无形可扩展记录
示例:
让我们说我有一张地图
val fromDB: Map[String, Any] = Map("name" -> "John", "age" -> 25)
知道字段“name”应该是一个字符串而字段“age”应该是一个整数,我如何将其转换为如下所示的无形可扩展记录?
val user = ("name" ->> "John") :: ("age" ->> 25) :: HNil
我的最终目标是创建一个如下对象,可以使用字段“fromDB”转换Map。
object User {
object name extends FieldOf[String]
object age extends FieldOf[Int]
def fromDB(data: Map[String,Any]) = {
//TODO
}
}
我也愿意接受其他建议以及这样做的方法。感谢。
答案 0 :(得分:10)
你可以使用TypeCase
提取器来写得非常干净:
import shapeless._, syntax.singleton._
val StrCase = TypeCase[String]
val IntCase = TypeCase[Int]
def toUserRecord(m: Map[String, Any]) = for {
StrCase(name) <- m.get("name")
IntCase(age) <- m.get("age")
} yield ("name" ->> name) :: ("age" ->> age) :: HNil
或者你可以让演员更加明确:
import syntax.typeable._
def toUserRecord(m: Map[String, Any]) = for {
name <- m.get("name").flatMap(_.cast[String])
age <- m.get("age").flatMap(_.cast[Int])
} yield ("name" ->> name) :: ("age" ->> age) :: HNil
请注意,我正在返回Option[LongRecordTypeHere]
以保持此类型安全 - 如果地图中不存在键或者值无法转换为正确类型,我们将获得None
。