Добавьте вложенные поля в JSON с помощью Circe

Проблема

Как добавить поля в объект 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"
      }
    ]
  }
}

ах, извините, не хотел использовать их повторно, я отредактирую.

Jackson Li 04.05.2024 01:32
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
1
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Рекурсивная функция использует сопоставление с образцом для преобразования списка подполей (из разделения полей по разделителю) во вложенный 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"}' неправильного типа, ожидается массив: ...'

Jackson Li 06.05.2024 00:58

Не уверен, что имеется в виду, поскольку вывод теперь кажется несоответствующим вводу.

ELinda 07.05.2024 17:37

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