Scala案例类递归

时间:2015-05-14 04:09:19

标签: scala recursion

我试图以递归方式从分层案例类结构中创建一个键值对映射,但没有运气。

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。

1 个答案:

答案 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)))))