2

JSON 解析:http ://www.dota2.com/jsfeed/heropickerdata?v=18874723138974056&l=english

Hero 类和 JSON 序列化

case class Hero(
    var id:Option[Int],
    name: String,
    bio: String,
        var trueName:Option[String]
){}
implicit val modelReader: Reads[Hero] = Json.reads[Hero]

读取数据

val future: Future[play.api.libs.ws.Response] = WS.url("http://www.dota2.com/jsfeed/heropickerdata?v=18874723138974056&l=english").get()
val json = Json.parse(Await.result(future,5 seconds).body).as[Map[String, Hero]]

var i = 1
json.foreach(p => { 
            p._2.trueName = Some(p._1)
    p._2.id = Some(i)
    p._2.commitToDatabase
    i += 1
})

我需要得到每个英雄的id。json 中英雄的顺序与他们的 id 匹配。显然,地图是无序的并且不会工作。有没有人有任何其他想法?

我尝试使用 LinkedHashMap。我什至尝试为 LinkedHashMap 进行隐式读取,但失败了。如果有人认为这是答案,那么您能给我一些指导吗?

它一直在说“找不到类型 scala.collection.mutable.LinkedHashMap[String,models.Hero] 的 Json 反序列化器。尝试为这种类型实现隐式读取或格式。”。我将特征导入到我要读取的文件中。我有一种有趣的感觉,即我的 Reads 中的最后一行是问题所在。我想我不能只做 asInstanceOf,但是我对如何做这个读取没有其他想法。

LinkedHashMap 隐式读取代码: http: //pastebin.com/cf5NpSCX

4

1 回答 1

0

JsObject您可以尝试直接从返回的 by中按顺序提取数据Json.parse,可能是这样的:

val json = Json.parse(Await.result(future,5 seconds).body)
val heroes: Map[String, Hero] = json match {
  case obj: JsObject => 
    obj.fields.zipWithIndex.map{ case ((name: String, heroJson: JsValue), id) =>
      heroJson.asOpt[Hero].map{ _.copy(id = Some(id)) }
    }.flatten.toMap
  case _ = > Seq.empty
}

我不相信您将不再需要保留顺序的地图,因为 ID 已生成并已修复。

于 2013-09-04T09:45:02.310 回答