Play Framework:如何按字母顺序排序JSON

j3d*_*j3d 3 json scala playframework

鉴于以下JSON ......

{
   "z": 100,
   "b": 50,
   "q": 12
}
Run Code Online (Sandbox Code Playgroud)

如何按字母顺序对键进行排序?

Mic*_*jac 7

很简单,但(显然)我们需要确保我们有一个JsObject.

val js = Json.parse("""{
   "z": 100,
   "b": 50,
   "q": 12
}""")

val jsObject = js.as[JsObject] // Not actually safe, but bear with me
Run Code Online (Sandbox Code Playgroud)

字段被简单地存储在一个名为场fields作为Seq[(String, JsValue)].

scala> jsObject.fields
res5: Seq[(String, play.api.libs.json.JsValue)] = ListBuffer((z,100), (b,50), (q,12))
Run Code Online (Sandbox Code Playgroud)

我们可以JsObject使用相同的字段创建一个新的,除了已排序.

scala> JsObject(jsObject.fields.sortBy(_._1))
res6: play.api.libs.json.JsObject = {"b":50,"q":12,"z":100}
Run Code Online (Sandbox Code Playgroud)

早些时候,我提到使用as[JsObject]是不安全的,因为如果我们JsValue实际上是一个数组或字符串,它将抛出异常.处理JsValue此处的更安全的方法是模式匹配JsObject并对其进行排序,并且不对任何其他类型执行任何操作.创建一个递归排序所有键的方法非常简单:

def sortJs(js: JsValue): JsValue = js match {
    case JsObject(fields) => JsObject(fields.sortBy(_._1).map { case (k, v) => (k, sortJs(v)) })
    case _ => js
}

val js = Json.parse("""{
   "z": 100,
   "b": {"k": 1, "j": 3, "i": 98},
   "q": 12
}""")

scala> sortJs(js)
res8: play.api.libs.json.JsValue = {"b":{"i":98,"j":3,"k":1},"q":12,"z":100}
Run Code Online (Sandbox Code Playgroud)