Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play Framework: How to sort JSON alphabetically

Given the following JSON...

{
   "z": 100,
   "b": 50,
   "q": 12
}

How do I sort the keys alphabetically?

like image 639
j3d Avatar asked May 11 '15 21:05

j3d


People also ask

How do I sort items in JSON?

JSON return type is an array of objects. Hence sort method cannot be used directly to sort the array. However, we can use a comparer function as the argument of the 'sort' method to get the sorting implemented.

Can JSON be sorted?

About JSON Sorter Tool The purpose of the JSON Sorter tool is to sort key names and key values, this can be both alphabetical and numerical values, and can be sorted ascending or descending (reversed).

How do I sort a JSON object by name?

If you want guaranteed order, you need to use an array. This will require you to change your data structure. One option might be to make your data look like this: var json = [{ "name": "user1", "id": 3 }, { "name": "user2", "id": 6 }, { "name": "user3", "id": 1 }];


1 Answers

Simple enough, but (obviously) we need to make sure we have a JsObject.

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

val jsObject = js.as[JsObject] // Not actually safe, but bear with me

The fields are simply stored in a field called fields as a Seq[(String, JsValue)].

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

We can make a new JsObject with the same fields, except sorted.

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

Earlier, I mentioned using as[JsObject] is unsafe, because if our JsValue is actually an array or string, it will throw an exception. The safer way to handle a JsValue here would be to pattern match on JsObject and sort it, and do nothing to any other type. It is simple enough to create a method that recursively sorts all keys:

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}
like image 163
Michael Zajac Avatar answered Sep 29 '22 17:09

Michael Zajac