如何在scala中正确创建树

时间:2017-06-01 20:25:06

标签: scala playframework play-json

我最近在工作中遇到了这个问题,并且无法弄清楚如何使用Scala完成它。我正在使用play框架,所以我可以访问JSON库。我是Scala的新手,想知道如何完成这项具体任务。示例数据是真实数据的示例。

最后,我无法解决这个问题,而是在这个Scala API的PHP使用者中解析数据。我想改变它:)

谢谢!

鉴于以下问题:

(("GET","a/b/c"),("POST","a/c/d"),("POST","f/e/x/r"),("GET","a/c/f/f"))

生成以下JSON:

{
  "a": {
    "b": {
      "c": {
        "GET" : "GET"
      }
    },

    "c": {
      "d": {
        "POST": "POST"
      },

      "f": {
        "f": {
          "GET": "GET"
        }
      }
    }
  },

  "f": {
    "e": {
      "x": {
        "r": {
          "POST": "POST"
        }
      }
    }
  }
}

1 个答案:

答案 0 :(得分:4)

首先,您可能不希望您的数据处于元组中。元组用于在静态固定数字中保存不同类型的值。你最好使用List[(String, String)],它允许你添加任意数量的路线(而你的例子只有4个)

接下来,如果路径中包含不同的段,则需要递归嵌套对象。使用foldRight

可以非常轻松地完成此操作
def nestedObjects(inside: JsObject, nesters: Seq[String]): JsObject = 
  nesters.foldRight(inside)((nester, in) => Json.obj(nester -> in)

现在,我们需要从给定的路径中提取nesters列表,并定义内部对象:

def treatPair(method: String, path: String): JsObject = {
  val nesters = path.split("/")
  val inside = Json.obj(method -> method)
  nestedObjects(inside, nesters)
}

现在,我们要合并所有结果,play-json已经有了一个方法:deepMerge

def reduceList(routes: List[(String, String)]): JsObject = {
  routes.map {
    case (method, path) => treatPair(method, path) //apply treatPair on each pair
  }.fold(Json.obj())(_ deepMerge _) //merge them two-by-two