динамически объединить два jsvalue и сопоставить дочернему элементу в play scala
Имею следующее:
x = [{"value":"cricket","key":"sports"},{"value":"hockey","key":"c"},{"value":"maharastra","key":"states"},{"value":"haryana","key":"states"},{"value":"facebook","key":"company"},{"value":"google","key":"company"}]
y = [{"Id":"India","label":"sports"},{"Id":"India","label":"states"},{"Id":"usa","label":"company"}]
Для каждой метки идентификатора jsvalue(y) сопоставлен ввод другого jsValue(x), я хочу сопоставить их, чтобы сформировать структуру ниже
"Mergedjson": [
{
"label":"India",
"children":[
{
"label":"Sports",
"children":[
{
"value":"Cricket",
"enable": y
},
{
"value":"hockey",
"enable": y
}
]
},
{
"label":"sates",
"children":[
{
"value":"maharastra",
"enable": y
},
{
"value":"Haryana",
"enable": y
}
]
}
]
},
{
"label":"USA",
"children":[
{
"label":"companies",
"children":[
{
"value":"google",
"enable": y
},
{
"value":"facebook",
"enable": y
}
]
}
]
}
]
Все, о чем я могу думать, - это напрямую объединить эти jsons, в результате чего у меня будет одно единственное jsValues для x и y, но не для вышеупомянутой структуры. заранее спасибо
2 ответа
Начнем с определения
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)))
код на ВыполнитеСкэсти .
Играть сама и играть в 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 в окно и вместо этого использовать circe.