简体   繁体   English

在Scala中,如何为Map [IndexedSeq [String],Int]编写一个高效的json格式化程序?

[英]In Scala, how to write an efficient json formatter for Map[IndexedSeq[String], Int]?

I think there is not a default format for Map[IndexedSeq[String], Int] in scala (right?) So I've written my own format as follows, however it's very slow. 我认为scala中没有Map [IndexedSeq [String],Int]的默认格式(对吧?)所以我写了我自己的格式如下,但是它很慢。 Is there a better way to do this? 有一个更好的方法吗?

class IndexedSeqToIntMapFormat() extends Format[Map[IndexedSeq[String], Int]] {

 def writes(o: Map[IndexedSeq[String], Int]): JsValue = {
   val mapItems: Seq[String] = o.toSeq.map{case (rowKey, index) => (index.toString +: rowKey).mkString(",")}
   Json.obj("items" -> Json.toJson(mapItems))
 }

 def reads(json: JsValue): JsResult[Map[IndexedSeq[String], Int]] = {
   val mapItemsAsString: IndexedSeq[String] = (json \ "items").as[IndexedSeq[String]]
   val map: Map[IndexedSeq[String], Int] = mapItemsAsString.map(itemAsString => {
     val item: IndexedSeq[String] = itemAsString.split(",").toIndexedSeq
     val rowKey: IndexedSeq[String] = item.tail
     val rowIndex: Int = item.head.toInt
     (rowKey, rowIndex)
   }).toMap

   JsSuccess(map)
 }
}

Thanks! 谢谢!

Can't say for sure whether the following approach is significantly faster than yours, but to my understanding, it does much more conform to the "spirit" of JSON. 不能肯定地说下面的方法是否明显快于你的,但根据我的理解,它更符合JSON的“精神”。 In a JSON serialization, each object and all its sub-objects and attributes should be named, by what they are. 在JSON序列化中,每个对象及其所有子对象和属性都应按它们的名称命名。 A list of custom string serializations of complex objects is not an actual JSON representation in my opinion. 在我看来,复杂对象的自定义字符串序列化列表不是真正的JSON表示。

Doing it in a "proper" JSON way should at least save some time in the parsing, as it does not require additional parsing work on strings but already provides all data in the needed places. 以“适当的”JSON方式执行它应该至少节省一些时间在解析中,因为它不需要对字符串进行额外的解析工作,但已经在所需的位置提供了所有数据。 And the code looks much more readable :-) 并且代码看起来更具有可读性:-)

The resulting JSON should look like this: 生成的JSON应如下所示:

"items": [
  { "keySeq": [ "key1", "key2", "key3" ], "value": 42 },
  { "keySeq": [ "key4", "key5" ], "value": 123 },
  { "keySeq": [ "key6", "key7", "key7" ], "value": 650 }
]

The formatter could be something like this: 格式化程序可能是这样的:

class IndexedSeqToIntMapFormat() extends Format[Map[IndexedSeq[String], Int]] {

  def writes(m: Map[IndexedSeq[String], Int]): JsValue = {
    val objs = m.toSeq.map { case (keySeq, value) =>
      Json.obj("keySeq" -> Json.toJson(keySeq), "value" -> JsNumber(value))
    }
    Json.obj("items" -> JsArray(objs))
  }

  def reads(json: JsValue): JsResult[Map[IndexedSeq[String], Int]] = {
    val seq = (json \ "items").as[Seq[JsValue]] map { obj =>
      ( (obj \ "keySeq").as[IndexedSeq[String]], (obj \ "value").as[Int] )
    }
    JsSuccess(seq.toMap)
  }
}

By the way, just out of curiosity - can you tell me in what context you need a such map? 顺便说一句,出于好奇 - 你能告诉我你需要一个这样的地图吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM