Как добавить поля в объект Json, если поле вложенное?
Это похоже на этот форум: Добавление поля в JSON с помощью Circe
но вместо:
{
ExistingField: {},
"Newfield" : {}
}
моя конечная цель что-то вроде:
{
ExistingField: {},
"A" : {
"B" : {
"C" : "myStringValue"
}
},
"AA" : {
"BB" : "myStringValue"
}
}
У меня есть список вложенных полей типа String, которые я хотел бы перебрать и добавить.
Вместо того, чтобы они были вложенными, я просто получил:
{
ExistingField: {},
"A.B.C" : "myStringValue"
}
мой список полей выглядит так:
val listOfFields: List[String] = List("A.B.C", "AA.BB")
Обновлено: Что, если добавленное поле представляет собой массив? например:
{
ExistingField: {},
"A" : {
"B" : {
"C" : "myStringValue"
}
},
"AA" : {
"BB" : [
{
"CC": "myStringValue"
},
{
"CC": "myStringValue"
}
]
}
}

Рекурсивная функция использует сопоставление с образцом для преобразования списка подполей (из разделения полей по разделителю) во вложенный Json, который затем можно преобразовать в исходный Json. deepMerge делает это несколько раз для каждого изначально указанного поля.
import io.circe.generic.auto._
import io.circe.parser
import io.circe.syntax._
import io.circe.Json
val jsonStr = """{"Fieldalreadythere": {}}"""
val jsonParse = parser.parse(jsonStr)
val listOfFields: List[String] = List("A.B.C", "AA.BB")
val listOfSplitFields = listOfFields.map(_.split("\\.").toList)
def makeJson(list: List[String]): Json = {
list match {
case h :: Nil => Json.fromFields(List((h, Json.fromString("stringValue"))))
case h :: t => Json.fromFields(List(h -> makeJson(t)))
case Nil => Json.fromFields(Nil)
}
}
val originalJson = jsonParse match {
case Right(value) => value.asObject
case Left(error) => throw error
}
val updateJsons = listOfSplitFields.map(makeJson(_))
updateJsons.foldLeft(originalJson.asJson)(_.deepMerge(_))
Результат (типа foldLeft):
{
"AA" : {
"BB" : "stringValue"
},
"A" : {
"B" : {
"C" : "stringValue"
}
},
"Fieldalreadythere" : {
}
}
Привет, спасибо за это решение. Я заметил, что у меня есть одно поле, которое представляет собой массив, а не строковое поле. Я обновил исходное сообщение в разделе «Обновлено:», чтобы показать, что я имею в виду. Я пытался отредактировать рекурсивную функцию, но продолжал получать: Получено значение '{"CC":"myStringValue"}' неправильного типа, ожидается массив: ...'
Не уверен, что имеется в виду, поскольку вывод теперь кажется несоответствующим вводу.
ах, извините, не хотел использовать их повторно, я отредактирую.