Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Format JSON string in scala

Is there a straight forward way to format a JSON string in scala?

I have a JSON String like this:

val json = {"foo": {"bar": {"baz": T}}}

Can I use a function f such that:

f(json) = {
           "foo": 
                {"bar": 
                       {"baz": T}
                }
           }

I know the formatting I have done in my answer is no perfect, but you get the point. And yes, can it be done without using Play Framework?

like image 240
Core_Dumped Avatar asked Jan 27 '14 18:01

Core_Dumped


People also ask

How to convert JSON string to Scala object?

Use the Lift-JSON library to convert a JSON string to an instance of a case class. This is referred to as deserializing the string into an object. Once you have a JValue object, use its extract method to create a MailServer object: val mailServer ...

Which of the following methods convert a JavaScript object to and from a JSON string?

Stringify a JavaScript Object Use the JavaScript function JSON.stringify() to convert it into a string. const myJSON = JSON.stringify(obj); The result will be a string following the JSON notation.


2 Answers

In case you are using Play Framework you could use Json.prettyPrint method to format JsValue:

import play.api.libs.json.Json

val str = """{"foo": {"bar": {"baz": "T"}}}"""

val jsValue = Json parse str
// JsValue = {"foo":{"bar":{"baz":"T"}}}

Json prettyPrint jsValue
// String = 
// {
//   "foo" : {
//     "bar" : {
//       "baz" : "T"
//     }
//   }
// }

In case you are using scala.util.parsing.json you have to create such method by yourself. For instance:

def format(t: Any, i: Int = 0): String = t match {
  case o: JSONObject =>
    o.obj.map{ case (k, v) =>
      "  "*(i+1) + JSONFormat.defaultFormatter(k) + ": " + format(v, i+1)
    }.mkString("{\n", ",\n", "\n" + "  "*i + "}")

  case a: JSONArray =>
    a.list.map{
      e => "  "*(i+1) + format(e, i+1)
    }.mkString("[\n", ",\n", "\n" + "  "*i + "]")

  case _ => JSONFormat defaultFormatter t
}

val jsn = JSON.parseRaw("""{"foo": {"bar": {"baz": "T"}, "arr": [1, 2, "x"]}, "foo2": "a"}""").get
// JSONType = {"foo" : {"bar" : {"baz" : "T"}, "arr" : [1.0, 2.0, "x"]}, "foo2" : "a"}

format(jsn)
// String = 
// {
//   "foo": {
//     "bar": {
//       "baz": "T"
//     },
//     "arr": [
//       1.0,
//       2.0,
//       "x"
//     ]
//   },
//   "foo2": "a"
// }

Note that this is not an efficient implementation.

like image 88
senia Avatar answered Nov 08 '22 10:11

senia


I thought I read somewhere that Typesafe was considering separating their JSON processing out of Play, so look into that to apply @senia's solution first.

Otherwise, look at Jackson--or more precisely, the Scala wrapper for Jackson:

val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val writer = mapper.writerWithDefaultPrettyPrinter
val json = writer.writeValueAsString(Object value)

I've also heard that the kids are really into Scala Pickling, which apparently has pretty printing as well.

like image 3
Vidya Avatar answered Nov 08 '22 11:11

Vidya