Play Framework:如何按字母顺序对JSON排序
给定以下JSONPlay Framework:如何按字母顺序对JSON排序,json,scala,playframework,Json,Scala,Playframework,给定以下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 这些字段只是以Seq[(String,Js
{
"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
这些字段只是以Seq[(String,JsValue)]
的形式存储在名为fields
的字段中
我们可以用相同的字段创建一个新的JsObject
,除了排序
scala> JsObject(jsObject.fields.sortBy(_._1))
res6: play.api.libs.json.JsObject = {"b":50,"q":12,"z":100}
前面,我提到将用作[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}
这对我来说很有用(通过以下测试):
- Scala版本:2.11.8
- 播放json版本:2.6.10
Just FTR:这是我在接受答案时遇到的错误:
scala> def sortJs(js: JsValue): JsValue = js match {
| case JsObject(fields) => JsObject(fields.sortBy(_._1).map { case (k, v) => (k, sortJs(v)) })
| case _ => js
| }
<console>:16: error: value sortBy is not a member of scala.collection.Map[String,play.api.libs.json.JsValue]
case JsObject(fields) => JsObject(fields.sortBy(_._1).map { case (k, v) => (k, sortJs(v)) })
^
<console>:16: error: type mismatch;
found : Any
required: play.api.libs.json.JsValue
case JsObject(fields) => JsObject(fields.sortBy(_._1).map { case (k, v) => (k, sortJs(v)) })
^
scala>def-sortJs(js:JsValue):JsValue=js-match{
|case-JsObject(fields)=>JsObject(fields.sortBy(u._1).map{case(k,v)=>(k,sortJs(v))})
|case=>js
| }
:16:错误:value sortBy不是scala.collection.Map[String,play.api.libs.json.JsValue]的成员
case-JsObject(fields)=>JsObject(fields.sortBy(u._1).map{case(k,v)=>(k,sortJs(v))})
^
:16:错误:类型不匹配;
发现:有吗
必需:play.api.libs.json.JsValue
case-JsObject(fields)=>JsObject(fields.sortBy(u._1).map{case(k,v)=>(k,sortJs(v))})
^
我遇到了与Yuchen在接受答案时遇到的相同问题。我就是这样让它工作的:
def sortJs(js: JsValue): JsValue = js match {
case JsObject(fields) => JsObject(fields.toSeq.sortBy(_._1).map { case (key, value) => (key, sortJs(value.asInstanceOf[JsValue]))})
case _ => js
}
上述版本不处理递归排序JsArray。这个版本可以处理这个问题
def sortJs(js: JsValue): JsValue = js match {
case JsObject(fields) => JsObject(fields.toSeq.sortBy(_._1).map { case (key, value) => (key, sortJs(value.asInstanceOf[JsValue])) })
case JsArray(array) => JsArray(array.map(e => sortJs(e)))
case other => other
}
def sortJs(js: JsValue): JsValue = js match {
case JsObject(fields) => JsObject(fields.toSeq.sortBy(_._1).map { case (key, value) => (key, sortJs(value.asInstanceOf[JsValue]))})
case _ => js
}
def sortJs(js: JsValue): JsValue = js match {
case JsObject(fields) => JsObject(fields.toSeq.sortBy(_._1).map { case (key, value) => (key, sortJs(value.asInstanceOf[JsValue])) })
case JsArray(array) => JsArray(array.map(e => sortJs(e)))
case other => other
}