I want to go from the following JSON:
我想从下面的JSON开始:
[
{
"name": "Cat",
"profile_image_url": "http://a0.twimg.com/profile_images/2284174872/7df3h38zabcvjylnyfe3_normal.png",
"location": "San Francisco, CA",
"id_str": "799346"
},
{
"name": "Dog",
"profile_image_url": "http://a0.twimg.com/profile_images/2284174758/v65oai7fxn47qv9nectx_normal.png",
"location": "San Francisco, CA",
"id_str": "783214"
}
]
to a Map[String, User]
, where the key is the name, and the User is the object that looks like this:
对于Map[String, User],其中键是名称,而用户是这样的对象:
case class User(name: String, profileImage: String, id: String)
I'm using Play and Scala but am struggling to figure out how to do the JSON parsing.
我使用的是Play和Scala,但我很难弄清楚如何进行JSON解析。
3 个解决方案
#1
1
First you can define an instance of the Reads
type class for your type:
首先,您可以为您的类型定义read类型类的实例:
import play.api.libs.functional.syntax._
import play.api.libs.json._
implicit val userReads = (
(__ \ 'name).read[String] and
(__ \ 'profile_image_url).read[String] and
(__ \ 'id_str).read[String]
)(User.apply _)
And then you get a Reads[List[User]]
instance for free that will decode your JSON:
然后你会得到一个读取[List[User]]]]的实例,它会解码你的JSON:
Json.parse(jsonString).validate[List[User]]
That's not exactly what you want, but you can turn the list into a map pretty easily:
这不是你想要的,但是你可以很容易地把列表变成一张地图:
Json.parse(jsonString).validate[List[User]].map(_.map(u => u.name -> u).toMap)
And now you've got a JsResult[Map[String, User]]
.
现在您有了一个JsResult[Map[String, User]]]。
#2
0
Alternatively, maybe you can use argonaut, it provides more friendly api.
或者,您可以使用argonaut,它提供更友好的api。
val json: String = """[
{
"name": "Cat",
"profile_image_url": "http://a0.twimg.com/profile_images/2284174872/7df3h38zabcvjylnyfe3_normal.png",
"location": "San Francisco, CA",
"id_str": "799346"
},
{
"name": "Dog",
"profile_image_url": "http://a0.twimg.com/profile_images/2284174758/v65oai7fxn47qv9nectx_normal.png",
"location": "San Francisco, CA",
"id_str": "783214"
}
]"""
import argonaut._, Argonaut._
case class User(name: String, url: String, location: String, idStr: String)
implicit def UserCodecJson =
casecodec4(User.apply, User.unapply)("name", "profile_image_url", "location", "id_str")
val result = json.decodeValidation[List[User]]
println(result) //Success(List(User(Cat,http://a0.twimg.com/profile ....
The good thing about this result is Scalaz Validation, because Validation is monad, so you can bind (flatmap) it with other Validation.
这个结果的好处是Scalaz验证,因为验证是monad,所以您可以将它与其他验证绑定(flatmap)。
#3
0
You can try this way:
你可以这样尝试:
1 Define you Case class with format:
1用格式定义你的Case类:
case class User(name: String, profileImage: String, id: String) {
implicit val jsonFormat: Format[User] = Json.format[User]
}
2 parsing your json as List[User]
2将json解析为列表[用户]
val jsonStr: String = ...
val users = Json.parse(jsonStr).as[List[User]]
3 group your List[User] to Map[String, User]
3组您的列表[用户]映射[String, User]
val whatYourWant:Map[String, User] = users.groupBy(_.name)
#1
1
First you can define an instance of the Reads
type class for your type:
首先,您可以为您的类型定义read类型类的实例:
import play.api.libs.functional.syntax._
import play.api.libs.json._
implicit val userReads = (
(__ \ 'name).read[String] and
(__ \ 'profile_image_url).read[String] and
(__ \ 'id_str).read[String]
)(User.apply _)
And then you get a Reads[List[User]]
instance for free that will decode your JSON:
然后你会得到一个读取[List[User]]]]的实例,它会解码你的JSON:
Json.parse(jsonString).validate[List[User]]
That's not exactly what you want, but you can turn the list into a map pretty easily:
这不是你想要的,但是你可以很容易地把列表变成一张地图:
Json.parse(jsonString).validate[List[User]].map(_.map(u => u.name -> u).toMap)
And now you've got a JsResult[Map[String, User]]
.
现在您有了一个JsResult[Map[String, User]]]。
#2
0
Alternatively, maybe you can use argonaut, it provides more friendly api.
或者,您可以使用argonaut,它提供更友好的api。
val json: String = """[
{
"name": "Cat",
"profile_image_url": "http://a0.twimg.com/profile_images/2284174872/7df3h38zabcvjylnyfe3_normal.png",
"location": "San Francisco, CA",
"id_str": "799346"
},
{
"name": "Dog",
"profile_image_url": "http://a0.twimg.com/profile_images/2284174758/v65oai7fxn47qv9nectx_normal.png",
"location": "San Francisco, CA",
"id_str": "783214"
}
]"""
import argonaut._, Argonaut._
case class User(name: String, url: String, location: String, idStr: String)
implicit def UserCodecJson =
casecodec4(User.apply, User.unapply)("name", "profile_image_url", "location", "id_str")
val result = json.decodeValidation[List[User]]
println(result) //Success(List(User(Cat,http://a0.twimg.com/profile ....
The good thing about this result is Scalaz Validation, because Validation is monad, so you can bind (flatmap) it with other Validation.
这个结果的好处是Scalaz验证,因为验证是monad,所以您可以将它与其他验证绑定(flatmap)。
#3
0
You can try this way:
你可以这样尝试:
1 Define you Case class with format:
1用格式定义你的Case类:
case class User(name: String, profileImage: String, id: String) {
implicit val jsonFormat: Format[User] = Json.format[User]
}
2 parsing your json as List[User]
2将json解析为列表[用户]
val jsonStr: String = ...
val users = Json.parse(jsonStr).as[List[User]]
3 group your List[User] to Map[String, User]
3组您的列表[用户]映射[String, User]
val whatYourWant:Map[String, User] = users.groupBy(_.name)