我试图以递归方式从分层案例类结构中创建一个键值对映射,但没有运气。
case class Country(id: Option[Long], name: String, states: Option[List[State]])
case class State(id: Option[Long], name: String, cities: Option[List[City]])
case class City(id: Option[Long], name: String)
所以我试图在Lists和zip中提取它以获取键值对,然后尝试进行一些递归计算以在对象列表中获得相同的值。
val keys = country.getClass.getDeclaredFields.map(f => f.getName)
val values = country.productIterator
val m = (keys zip values.toList).toMap
这给了我3个键的值。
我的问题是解决国家内List [City]和Country内List [State]的递归方式。
有没有好办法呢?我想不出任何好的解决方案。我试图迭代地图,匹配有List的地方并迭代并尝试将此进程保存在BufferList中。
有没有人试图做这样的事情?
修改
我没有具体说明理想的输出。
我希望孩子成为其他地图,所以从@Tienan Ren那里得到例子我尝试做这样的事情:
def toMap[T: TypeTag](clazz: scala.Product): Map[String, Any] = {
def recursion(key: String, list: List[T]): Map[String, Any] = {
list.toMap
}
val keys = clazz.getClass.getDeclaredFields.map(_.getName)
val values = (keys zip clazz.productIterator.toList) map {
case (key, value: List[T]) => recursion(key, value)
case (key, value) => (key, value)
}
values.toMap
}
递归应该接收列表并返回Map。
答案 0 :(得分:1)
不确定为什么要使用Option [List [..]],空列表应该能够代表None情况。这是删除列表选项后的实现。
case class Country(id: Option[Long], name: String, states: List[State])
case class State(id: Option[Long], name: String, cities: List[City])
case class City(id: Option[Long], name: String)
toMap功能:
import reflect.runtime.universe._
def toMap[T: TypeTag](c: scala.Product): Map[String, Any] = {
val keys = c.getClass.getDeclaredFields.map(_.getName)
val z = (keys zip c.productIterator.toList) map {
case (key, value: List[T]) if typeOf[T] <:< typeOf[scala.Product] =>
(key, value.map(v => toMap(v.asInstanceOf[scala.Product])))
case (key, value) => (key, value)
}
z.toMap
}
输出:
val country = Country(None, "US", List(State(None, "CA", City(None, "LA") :: Nil)))
println(toMap(country))
这会给你:
Map(id -> None, name -> US, states -> List(Map(id -> None, name -> CA, cities -> List(Map(id -> None, name -> LA)))))