问题描述
我有以下几点:
x = [{"value":"cricket","key":"sports"},{"value":"hockey","key":"c"},{"value":"maharastra","key":"states"},{"value":"haryana",{"value":"facebook","key":"company"},{"value":"google","key":"company"}]
y = [{"Id":"India","label":"sports"},{"Id":"India","label":"states"},{"Id":"usa","label":"company"}]
对于 jsvalue(y) 的 Id 的每个标签都映射到另一个 jsValue(x) 中的键,我想将它们映射为以下结构:
{
"Mergedjson": [
{
"label": "India","children": [
{
"label": "Sports","children": [
{
"value": "Cricket","enable": false
},{
"value": "hockey","enable": false
}
]
},{
"label": "sates","children": [
{
"value": "maharastra",{
"value": "Haryana","enable": false
}
]
}
]
},{
"label": "USA","children": [
{
"label": "companies","children": [
{
"value": "google",{
"value": "facebook","enable": false
}
]
}
]
}
]
}
我能想到的就是直接合并这些 json,最终得到 x 和 y 的单个 jsValue
但不是上述结构。
解决方法
我们将从定义 X
和 Y
及其格式化程序开始:
case class X(value: String,key: String)
object X {
implicit val format: OFormat[X] = Json.format[X]
}
case class Y(Id: String,label: String)
object Y {
implicit val format: OFormat[Y] = Json.format[Y]
}
然后,假设我们成功解析了 x
和 y
:
val xs = Json.parse(x).validate[Seq[X]].getOrElse(???)
val ys = Json.parse(y).validate[Seq[Y]].getOrElse(???)
我们可以先从subLabels
创建xs
:
val subLabels = xs.groupBy(_.key).map {
case (value,s) =>
val values = s.map(x => JsObject(Map("value" -> JsString(x.value),"enable" -> JsFalse)))
value -> JsObject(Map("label" -> JsString(value),"children" -> JsArray(values)))
}
然后使用它自己创建标签:
val labels = ys.groupBy(_.Id).map {
case (id,s) =>
JsObject(Map("label" -> JsString(id),"children" -> JsArray(s.map(_.label).flatMap(subLabels.get))))
}
最终的 json 将是:
val result = JsObject(Map("Mergedjson" -> JsArray(labels.toSeq)))
代码在 Scastie 运行。
,播放自己并播放 json 尤其不是最好的工作,但这样的事情会起作用:
val x: JsArray = ???
val y: JsArray = ???
val y1 = y.value.map{x => (x \ "key",x)}.toMap
val x1 = Json.toJson(x.value.map{obj =>
val v = obj.asInstanceOf[JsObject].values.toMap
Json.toJson(v.updated("Id",y1(v("Id"))))
})
我建议你将 play json 扔到 window 并使用 circe 代替。