我最近在工作中遇到了这个问题,并且无法弄清楚如何使用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"
}
}
}
}
}
答案 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