Измените значения json из списка карт и сохраните вывод

У меня есть следующий пример 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"
}

Можете ли вы предоставить ожидаемый результат для JSON, который вы предоставили в начале?

Bentaye 25.04.2018 12:18

@Bentaye Я добавил пример вывода для первого появления ввода

Curious_Bop 25.04.2018 12:27
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
2
419
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Учитывая следующий список замен:

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] для работы с тем, что у нас есть выше?

Curious_Bop 25.04.2018 15:14

Просто замените Map на mutable.Map в моем ответе, все должно работать нормально. Отредактировал свой ответ с помощью mutable.Map. Я также отредактировал ваш вопрос с этой информацией.

Bentaye 25.04.2018 15:19

Возможно, вы знаете, как лучше всего записать каждый объект JsObject в файл .json?

Curious_Bop 25.04.2018 16:28

@Curious_Bop Я добавил простой пример, вы можете изменить его, чтобы настроить имена файлов.

Bentaye 25.04.2018 16:48

еще раз, что мой ключ должен быть для изменения значений в гнезде, например, гнездо a = dummy? Я распечатываю все ключи в jsobject, но только классы вкладываются как ключ

Curious_Bop 26.04.2018 09:33

@Curious_Bop Действительно, он не работал для вложенных объектов. Я изменил его, чтобы учесть их. Перечитайте весь ответ, я повсюду немного поменял. :) Работаю сейчас.

Bentaye 26.04.2018 11:42

Позвольте нам продолжить обсуждение в чате.

Curious_Bop 26.04.2018 17:02

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