代码之家  ›  专栏  ›  技术社区  ›  sujit

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

  •  1
  • sujit  · 技术社区  · 7 年前

    我有一个沉重的巢穴 Map[String, Any] (从解析的JSON获得)。我的目的是通过在映射中递归并从Map key+值填充对象,将其转换为case类对象的列表。我在用 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 回复  |  直到 7 年前
        1
  •  2
  •   slouc    7 年前

    转动 Map 变成一个 List 很容易通过地图的方法完成 .toList ,它将映射转换为(键、值)元组的列表。一旦你有了一个列表,你就可以用一个返回列表的函数来平面映射它。

    但是,如果使用这样的函数(即返回列表的函数)对映射进行平面映射,编译器将推断出最近的列表和映射的公共超类型,这是一个Iterable。这就是你的情况。

    所以,只要换成

    map.toList.flatMap {
    

    应该会成功的。

    推荐文章