У меня есть следующий пример json, который я прочитал, используя платформу воспроизведения.
{
"field_a": "dummy",
"field_b": "dummy",
"nest": {
"nest_a": "dummy",
"nest_b": 87
},
"field_c": null,
"field_d": null,
"field_e": "chocolate",
"field_f": "sugar",
"array": [
"dummy entry"
],
"id": "Anything"
}
Затем у меня есть следующий список карт, которые я хочу поменять местами, которые являются моим Вход:
val substitutionsList: List[mutable.Map[String, String]] = List(
mutable.Map("field_b" -> "dummy string", "field_d" -> "2016-01-01", "field_f" -> "2011-01-01"),
mutable.Map("field_b" -> "dummy string", "field_d" -> "2018-01-01", "field_f" -> "2018-01-01"),
mutable.Map("field_b" -> "dummy string", "field_d" -> "2018-04-01", "field_f" -> "2018-04-01"),
mutable.Map("field_b" -> "dummy string", "field_d" -> "2016-01-01", "field_f" -> "2016-01-01")
)
Я читаю в json следующее:
def parseSchemaJson(schemaContent: String) = Json.parse(schemaContent).as[JsObject]
val baseSchemaInput = parseSchemaJson(Source.fromFile("/dummy.json").mkString)
Я хочу перебрать свой ввод и поменять значения в json на значения на моей карте, и после каждого из них создать новый файл .json.
private def replaceField(json: JsObject, fieldToReplace: String): Option[String] = (json \ fieldToReplace).asOpt[String]
println(replaceField(baseSchemaInput, "field_a")) //prints dummy
Я могу перечислить значение в моем json, используя что-то вроде этого, но я понятия не имею, как заменить значение из моего списка на каждый соответствующий бит и записать файл json.
Первое появление ожидаемого результата
{
"field_a": "dummy",
"field_b": "dummy string",
"nest": {
"nest_a": "dummy",
"nest_b": 87
},
"field_c": null,
"field_d": "2016-01-01",
"field_e": "chocolate",
"field_f": "2011-01-01",
"array": [
"dummy entry"
],
"id": "Anything"
}
@Bentaye Я добавил пример вывода для первого появления ввода

Учитывая следующий список замен:
val substitutionsList: List[mutable.Map[String, Any]] = List(
mutable.Map("field_b" -> "dummy string 1", "field_d" -> "2016-01-01", "field_f" -> "2011-01-01"),
mutable.Map("field_b" -> "dummy string 2", "nest" -> mutable.Map("nest_b" -> "90"))
)
Обратите внимание, что второй обновляет вложенное значение. Вам необходимо создать вложенный Map для определения вложенных значений.
Вы можете определить функцию для преобразования Map[String, Any] (Any, потому что мы можем иметь либо String, либо Map в качестве значения) в JsObject. Это рекурсивная функция, которая будет вызывать сама себя, если значение равно Map.
def mapToJsObject(map: mutable.Map[String, Any]): JsObject =
JsObject(map.mapValues {
case v:String => JsString(v)
case v:mutable.Map[String, mutable.Map[String, Any]] => mapToJsObject(v.asInstanceOf[mutable.Map[String, Any]])
})
Затем просмотрите свой список замен и выполните глубокое слияние JsObject, сделанного из каждого Map, с исходным JsObject, используя функцию deepMerge, определенную в классе JsObject. Он также объединит вложенные объекты. См. API здесь
val substitutedJsObjects: List[JsObject] = substitutionsList
.map(mapToJsObject)
.map(baseSchemaInput.deepMerge)
Это должно дать вам список JsObjects, по одному на карту в вашем списке.
Затем вы можете записать их в файл. Вот пример записи одного файла на каждую строку json. Файлы будут называться 0.json, 1.json и т. д.
def writeToFile(jsObject: JsObject, fileName: String): Unit = {
println("writing "+fileName)
val pw = new PrintWriter(new File(fileName))
pw.write(jsObject.toString())
pw.close()
}
substitutedJsObjects.zipWithIndex.foreach {
case (jsObject, index) => {
val fileName = index.toString + ".json"
writeToFile(jsObject, fileName)
}
}
В моем примере вводом является List[mutable.Map[String, String]]. Как мы можем перенести это в Map[String, String] для работы с тем, что у нас есть выше?
Просто замените Map на mutable.Map в моем ответе, все должно работать нормально. Отредактировал свой ответ с помощью mutable.Map. Я также отредактировал ваш вопрос с этой информацией.
Возможно, вы знаете, как лучше всего записать каждый объект JsObject в файл .json?
@Curious_Bop Я добавил простой пример, вы можете изменить его, чтобы настроить имена файлов.
еще раз, что мой ключ должен быть для изменения значений в гнезде, например, гнездо a = dummy? Я распечатываю все ключи в jsobject, но только классы вкладываются как ключ
@Curious_Bop Действительно, он не работал для вложенных объектов. Я изменил его, чтобы учесть их. Перечитайте весь ответ, я повсюду немного поменял. :) Работаю сейчас.
Позвольте нам продолжить обсуждение в чате.
Можете ли вы предоставить ожидаемый результат для JSON, который вы предоставили в начале?