递归函数中的flatMap返回case类对象的List

时间:2018-07-25 08:50:41

标签: scala flatmap

我有一个高度嵌套的Map[String, Any](从解​​析的JSON中获取)。我的意图是通过遍历Map并从map key + value填充对象,将其转换(平化)为案例类对象列表。我在递归函数中使用flatMap,但遇到编译问题:

<console>:30: error: type mismatch;  found   : scala.collection.immutable.Iterable[Derived]  required: List[Derived]
         map.flatMap {
                     ^

我的代码如下。请指出我做错了什么以及如何解决?

case class Derived(a: String, b: String, c: String)
val Sep = "/"
def getDerivedList(map: Map[String, Any], prefix: String = Sep) : List[Derived] = {
  map.flatMap {
    //Handle Map as value by recursing
    case (k, v:Map[String, Any]) => getDerivedList(v, s"${prefix}${k}${Sep}")
    //Handle primitive type
    case (k, v) if (v != null && v != None) => {
      val value = if(v.isInstanceOf[Boolean]) String.valueOf(v).toUpperCase else String.valueOf(v)
      val a = "" //Custom logic from k or v
      val b = "" //Another custom logic from k or v
      val c = "" //You get it
      List(Derived(a,b,c))
    }
    case _ => List() //Catch all, will not come here as per my data
  }
}

val map: Map[String, Any] = Map("k1" -> "v1", "mk1" -> Map("mk1k2" -> "mk1v2", "mk1k3" -> Map("mk2k4" -> true)))
getDerivedList(map)

1 个答案:

答案 0 :(得分:2)

通过Map的方法Map可以轻松地将List转换为.toList,该方法将地图转换为(键,值)元组列表。拥有列表后,可以使用返回列表的函数对其进行平面映射。

但是,如果使用这样的函数(即返回List的函数)对Map进行平面映射,则编译器将推断List和Map的最接近的通用超类型,这是一个Iterable。这就是您的情况。

因此,只需更改为

map.toList.flatMap {

应该可以解决问题。