Nid*_*S G -1 json scala playframework-2.0
我是Scala的新手,请帮助我.我有2个Json文件.我想用第二个json中的键来排序第一个json.
例如:First Json
{
"id": 1,
"response" : [{
"user_id" : 1,
"products" : [
{
"product_id": 10,
"price": 200
},
{
"product_id": 13,
"price": 210
},
{
"product_id": 9,
"price": 320
}
]
},{
"user_id" : 2,
"products" : [
{
"product_id": 15,
"price": 200
},
{
"product_id": 13,
"price": 210
},
{
"product_id": 8,
"price": 320
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
而我的第二个Json
{
"sort": [
{
"user_id": 1,
"products": [
{
"id": 8,
"rank": 5
},
{
"id": 9,
"rank": 1
},
{
"id": 10,
"rank": 3
},
{
"id": 13,
"rank": 2
},{
"id": 15,
"rank": 6
},{
"id": 17,
"rank": 4
},{
"id": 20,
"rank": 7
},{
"id": 21,
"rank": 8
},{
"id": 23,
"rank": 9
}
]
},{
"user_id": 2,
"products": [
{
"id": 8,
"rank": 5
},
{
"id": 9,
"rank": 1
},
{
"id": 10,
"rank": 3
},
{
"id": 13,
"rank": 2
},{
"id": 15,
"rank": 6
},{
"id": 17,
"rank": 4
},{
"id": 20,
"rank": 7
},{
"id": 21,
"rank": 8
},{
"id": 23,
"rank": 9
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
我想根据我在第二个Json中的排名来排序我的第一个json.
输出应该像每个用户应该根据在第二个JSON上为每个用户指定的排名按顺序排列他的产品.
到目前为止,这是我尝试过的
def sortedRes() = Action.async {
val url = //1st json url
val sortUrl = //2nd json url
ws.url(url).get().map { response =>
val value: JsValue = Json.parse(response.body)
val result: Either[Exception, SampleResponses] = value.validate[SampleResponses] match {
case JsSuccess(searchResponse, _) =>
Right(searchResponse)
case JsError(errors) =>
Left(new Exception("Couldn't parse Search API response"))
}
val values: List[SampleResponse] = result.right.get.responses
ws.url(sortUrl).get().map { response =>
val sorted: JsValue = Json.parse(response.body)
val sortRespResult: Either[Exception, Sort] = sorted.validate[Sort] match {
case JsSuccess(sortResponse, _) =>
Right(sortResponse)
case JsError(errors) =>
Left(new Exception("Couldn't parse because of these errors : " + errors))
}
val prodRankDetails: List[SampleRank] = sortRespResult.right.get.sort
println("prod = " + prodRankDetails.head.products.sortWith(_.rank > _.rank))
}
Ok(Json.toJson(result.right.get))
}
}
Run Code Online (Sandbox Code Playgroud)
在最后一个打印语句中,我得到了第二个json的第一个用户产品.我想要得到的是我的第一个json基于第二个用户排序.
这是我的模特课
package models
import play.api.libs.functional.syntax._
import play.api.libs.json.Reads._
import play.api.libs.json._ // Combinator syntax
object sample {
case class SampleProduct(productId:Int, price: Int)
case class SampleResponse(userId: Int, products: List[SampleProduct])
case class SampleResponses(id: Int, responses: List[SampleResponse])
case class SampleRankedProduct(id: Int, rank: Int)
case class SampleRank(userId: Int, products: List[SampleRankedProduct])
case class Sort(sort: List[SampleRank])
implicit val productReads: Reads[SampleProduct] = (
(JsPath \ "product_id").read[Int] and
(JsPath \ "price").read[Int]
)(SampleProduct.apply _)
implicit val productWrites: Writes[SampleProduct] = (
(JsPath \ "product_id").write[Int] and
(JsPath \ "price ").write[Int]
)(unlift(SampleProduct.unapply))
implicit val responseReads: Reads[SampleResponse] = (
(JsPath \ "user_id").read[Int] and
(JsPath \ "products").read[List[SampleProduct]]
)(SampleResponse.apply _)
implicit val responseWrites: Writes[SampleResponse] = (
(JsPath \ "user_id").write[Int] and
(JsPath \ "products").write[List[SampleProduct]]
)(unlift(SampleResponse.unapply))
implicit val responsesReads: Reads[SampleResponses] = (
(JsPath \ "id").read[Int] and
(JsPath \ "response").read[List[SampleResponse]]
)(SampleResponses.apply _)
implicit val responsesWrites: Writes[SampleResponses] = (
(JsPath \ "id").write[Int] and
(JsPath \ "response").write[List[SampleResponse]]
)(unlift(SampleResponses.unapply))
implicit val rankedProductReads: Reads[SampleRankedProduct] = (
(JsPath \ "id").read[Int] and
(JsPath \ "rank").read[Int]
)(SampleRankedProduct.apply _)
implicit val rankedProductWrites: Writes[SampleRankedProduct] = (
(JsPath \ "id").write[Int] and
(JsPath \ "rank ").write[Int]
)(unlift(SampleRankedProduct.unapply))
implicit val rankReads: Reads[SampleRank] = (
(JsPath \ "user_id").read[Int] and
(JsPath \ "products").read[List[SampleRankedProduct]]
)(SampleRank.apply _)
implicit val rankWrites: Writes[SampleRank] = (
(JsPath \ "user_id").write[Int] and
(JsPath \ "products").write[List[SampleRankedProduct]]
)(unlift(SampleRank.unapply))
implicit val sortReads: Reads[Sort] = (JsPath \ "sort").read[List[SampleRank]].map(x ? Sort(x))
implicit val sortWrites: Writes[Sort] = (__ \ "sort").write[List[SampleRank]].contramap { (person: Sort) => person.sort }
}
Run Code Online (Sandbox Code Playgroud)
使用第二个JSON的排名对第一个JSON进行排序的方法是这样的:
....
val prodRankDetails: List[SampleRank] = sortRespResult.right.get.sort
val sortedResults = values.copy(
responses = values.responses.map { resultForUser =>
val rankingForUser = prodRankDetails
.find(_.userId == resultForUser.userId)
.getOrElse(throw new RuntimeException(s"Rank not found for user ${resultForUser.userId}"))
.products
.map(product => (product.id, product.rank))
.toMap
resultForUser.copy(
products = resultForUser.products.sortWith((a, b) =>
rankingForUser.getOrElse(a.productId, Int.MaxValue) < rankingForUser.getOrElse(b.productId, Int.MaxValue))
)
}
)
Ok(Json.toJson(sortedResults))
Run Code Online (Sandbox Code Playgroud)
这应该在你获得后立即执行prodRankDetails.而且,.map当您管理a时,响应将在内部提供Future.所以你必须移动Ok(...)地图内部和flatMap外部Future.
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
214 次 |
| 最近记录: |