给定以下JSON ...
{
"z": 100,
"b": 50,
"q": 12
}
如何按字母顺序对键进行排序?
最佳答案
很简单,但是(显然)我们需要确保我们有一个JsObject
。
val js = Json.parse("""{
"z": 100,
"b": 50,
"q": 12
}""")
val jsObject = js.as[JsObject] // Not actually safe, but bear with me
这些字段只是作为
fields
存储在称为Seq[(String, JsValue)]
的字段中。scala> jsObject.fields
res5: Seq[(String, play.api.libs.json.JsValue)] = ListBuffer((z,100), (b,50), (q,12))
我们可以使用相同的字段(排序除外)创建一个新的
JsObject
。scala> JsObject(jsObject.fields.sortBy(_._1))
res6: play.api.libs.json.JsObject = {"b":50,"q":12,"z":100}
之前,我提到使用
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}