logo language json scala serialization map lift

json - logo - packages r language



¿Cómo se serializa un mapa a JSON en Scala? (7)

¿Qué tal esto?

implicit val formats = net.liftweb.json.DefaultFormats import net.liftweb.json.JsonAST._ import net.liftweb.json.Extraction._ import net.liftweb.json.Printer._ val m = Map[String, String]( "a" -> "theA", "b" -> "theB", "c" -> "theC", "d" -> "theD", "e" -> "theE" ) println(compact(render(decompose(m))))

salida:

{"e":"theE","a":"theA","b":"theB","c":"theC","d":"theD"}

EDITAR:

Para un scala.collections.mutable.Map , primero debe convertirlo en un mapa inmutable: .toMap

Así que tengo un mapa en Scala como este:

val m = Map[String, String]( "a" -> "theA", "b" -> "theB", "c" -> "theC", "d" -> "theD", "e" -> "theE" )

y quiero serializar esta estructura en una cadena JSON usando lift-json.

¿Alguno de ustedes sabe cómo hacer esto?


Complementando la respuesta por @Raja.

Para aquellos objetos anidados, modifico localmente la clase para que mi quería toString() esta manera:

case class MList[T]() extends MutableList[T] { override def toString() = "[" + this.toList.mkString(",") + "]" }

Luego, dentro del objeto Mapa, uso este MList lugar de la List estándar. De esa manera, mi objeto de map imprime bien llamando a JSONObject(map).toString() .


De manera similar a la solución de Einar, puede usar JSONObject de Parser Combinators para hacer esto. Tenga en cuenta que no responde, tendrá que hacerlo usted mismo. La biblioteca también incluye JSONArray, para listas como estructuras de datos. Algo como lo siguiente abordará las preocupaciones de Noel sobre las estructuras anidadas. Este ejemplo no es recurrente a un nivel arbitrario, pero manejará un valor de Lista [Mapa [Cadena, Cualquiera]] .

import scala.util.parsing.json.{JSONArray, JSONObject} def toJson(m : Map[String, Any]): String = JSONObject( m.mapValues { case mp: Map[String, Any] => JSONObject(mp) case lm: List[Map[String, Any]] => JSONArray(lm.map(JSONObject(_))) case x => x } ).toString


Este código convertirá muchos objetos diferentes, y no requiere ninguna biblioteca más allá del scala.util.parsing.json._ . No manejará adecuadamente los casos de borde como los mapas con enteros como claves.

import scala.util.parsing.json.{JSONArray, JSONObject} def toJson(arr: List[Any]): JSONArray = { JSONArray(arr.map { case (innerMap: Map[String, Any]) => toJson(innerMap) case (innerArray: List[Any]) => toJson(innerArray) case (other) => other }) } def toJson(map: Map[String, Any]): JSONObject = { JSONObject(map.map { case (key, innerMap: Map[String, Any]) => (key, toJson(innerMap)) case (key, innerArray: List[Any]) => (key, toJson(innerArray)) case (key, other) => (key, other) }) }


Puede usar esta forma simple si está usando el marco de juego:

import play.api.libs.json._ Json.toJson(<your_map>)


Puedes rodar tu propio bastante fácilmente (sí, no dependencias). Este hace el manejo básico de los tipos y hará la recursión a diferencia de JSONObject que se mencionó:

import scala.collection.mutable.ListBuffer object JsonConverter { def toJson(o: Any) : String = { var json = new ListBuffer[String]() o match { case m: Map[_,_] => { for ( (k,v) <- m ) { var key = escape(k.asInstanceOf[String]) v match { case a: Map[_,_] => json += "/"" + key + "/":" + toJson(a) case a: List[_] => json += "/"" + key + "/":" + toJson(a) case a: Int => json += "/"" + key + "/":" + a case a: Boolean => json += "/"" + key + "/":" + a case a: String => json += "/"" + key + "/":/"" + escape(a) + "/"" case _ => ; } } } case m: List[_] => { var list = new ListBuffer[String]() for ( el <- m ) { el match { case a: Map[_,_] => list += toJson(a) case a: List[_] => list += toJson(a) case a: Int => list += a.toString() case a: Boolean => list += a.toString() case a: String => list += "/"" + escape(a) + "/"" case _ => ; } } return "[" + list.mkString(",") + "]" } case _ => ; } return "{" + json.mkString(",") + "}" } private def escape(s: String) : String = { return s.replaceAll("/"" , "/////""); } }

Puedes verlo en acción como

println(JsonConverter.toJson( Map("a"-> 1, "b" -> Map( "nes/"ted" -> "yeah{/"some/":true"), "c" -> List( 1, 2, "3", List( true, false, true, Map( "1"->"two", "3"->"four" ) ) ) ) ) ) {"a":1,"b":{"nes/"ted":"yeah{/"some/":true"},"c":[1,2,"3",[true,false,true,{"1":"two","3":"four"}]]}

(Es parte de una biblioteca GDAX de Coinbase que he escrito, consulte util.scala )


Si está utilizando la última Scala 2.10.xy superior:

println(scala.util.parsing.json.JSONObject(m))