动态合并两个 jsvalues 并映射到 play scala 中的孩子

问题描述

我有以下几点:

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 但不是上述结构。

解决方法

我们将从定义 XY 及其格式化程序开始:

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]
}

然后,假设我们成功解析了 xy

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 代替。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...