Динамически объединить два 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"}]

Для каждой метки Id jsvalue (y) отображается, чтобы ввести другой jsValue (x), я хочу сопоставить их, чтобы сформировать структуру ниже:

{
    "Mergedjson": [
        {
            "label": "India",
            "children": [
                {
                    "label": "Sports",
                    "children": [
                        {
                            "value": "Cricket",
                            "enable": false
                        },
                        {
                            "value": "hockey",
                            "enable": false
                        }
                    ]
                },
                {
                    "label": "sates",
                    "children": [
                        {
                            "value": "maharastra",
                            "enable": false
                        },
                        {
                            "value": "Haryana",
                            "enable": false
                        }
                    ]
                }
            ]
        },
        {
            "label": "USA",
            "children": [
                {
                    "label": "companies",
                    "children": [
                        {
                            "value": "google",
                            "enable": false
                        },
                        {
                            "value": "facebook",
                            "enable": false
                        }
                    ]
                }
            ]
        }
    ]
}

Все, что я могу придумать, - это напрямую объединить эти jsons, в результате чего у меня будет один единственный jsValue как x, так и y, но не вышеупомянутой структуры.

Ожидаемый результат не является допустимым JSON: нет фигурных скобок начала / конца объекта, недопустимое значение y.

Andriy Plokhotnyuk 05.04.2021 10:27

@AndriyPlokhotnyuk обновите выходной json с правильным форматом

Alok 05.04.2021 16:41

@TomerShetah да, спасибо

Alok 07.04.2021 19:13

Конечно, Алок! Удачного кодирования! Вы примете мой ответ?

Tomer Shetah 07.04.2021 19:16
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
4
121
2

Ответы 2

Играть сам и играть в 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.

Начнем с определения 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.

Другие вопросы по теме