如何在Scala中将Map序列化为JSON?

Jay*_*lor 22 serialization json scala map lift

所以我在Scala中有一个这样的地图:

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

我想使用lift-json将此结构序列化为JSON字符串.

你们中的任何人都知道怎么做吗?

小智 32

如果您使用的是最新的Scala 2.10.x及更高版本:

println(scala.util.parsing.json.JSONObject(m))
Run Code Online (Sandbox Code Playgroud)

  • 看起来它没有正确递归到对象中.例如,`Map("0" - > 1,"1" - > List(Map("2" - > 3)))`被字符串化为`{"0":1,"1":List(Map (2 - > 3))}`. (10认同)
  • 它已从Scala 2.11及更高版本中删除. (3认同)
  • @Soid看起来仍然存在:http://www.scala-lang.org/api/2.11.8/scala-parser-combinators/#scala.util.parsing.json.JSONObject (2认同)

小智 26

这个怎么样?

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))))
Run Code Online (Sandbox Code Playgroud)

输出:

{"e":"theE","a":"theA","b":"theB","c":"theC","d":"theD"}
Run Code Online (Sandbox Code Playgroud)

编辑:

对于a scala.collections.mutable.Map,您应该首先将其转换为不可变映射:.toMap

  • 当我将类型更改为scala.collections.mutable.Map时,输出变为:[{"_ 1":"d","_ 2":"theD"},{"_ 1":"a","_ 2": "THEA"},{ "_ 1": "C", "_ 2": "theC"},{ "_ 1": "b", "_ 2": "theB"},{ "_ 1": "E", "_2":"theE"}],这让我很伤心. (6认同)
  • 有一个简单的解决方法 - 只需在可变映射上调用.toMap以获取不可变的映射,然后再次正常工作. (4认同)

jar*_*jar 6

你可以很容易地自己滚动(yay,没有依赖).这个做了类型的基本处理,并且将进行递归,不像JSONObject提到的那样:

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("\"" , "\\\\\"");
  }
}
Run Code Online (Sandbox Code Playgroud)

你可以在行动中看到它

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"}]]}
Run Code Online (Sandbox Code Playgroud)

(它是我编写的Coinbase GDAX库的一部分,请参阅util.scala)


Hai*_*mei 5

如果使用播放框架,则可以使用以下简单方法:

import play.api.libs.json._

Json.toJson(<your_map>)
Run Code Online (Sandbox Code Playgroud)