Обновление PlayJson для элемента массива не работает

У меня есть json

val js =  Json.obj("val" -> Json.arr(Json.obj("a" -> Json.arr(1))))

И я хочу обновить его

Json.obj("val" -> Json.arr(Json.obj("a" -> Json.arr(1))))
  .transform((__ \\ "val") (0).json.update(__.read[JsArray].map { jsVal => println(jsVal); jsVal }))

В моем сообщении об обновлении ничего не печатается. и даже в отладку не заходите. Но методы pick находят этот элемент.

js.transform((__ \\ "val")(0).json.pick)

вернуть JsSuccess({"a":[1]},//val(0)) Я не могу понять почему. Может ли кто-нибудь помочь мне, как обновить точный элемент.

Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
0
493
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Ваша карта не вызывается, потому что read [JsArray] фактически возвращает JsError:

val js = Json.obj("val" -> Json.arr(Json.obj("a" -> Json.arr(1))))
val result1 = js.transform((__ \\ "val") (0).json.update(Reads.of[JsArray]))
println(result1)
// JsError(List((//val(0),List(JsonValidationError(List(error.expected.jsarray),WrappedArray())))))

Вы можете распечатать вызывающее его значение следующим образом:

val result2 = js.transform((__ \\ "val")(0).json.update(
  Reads(v => { println(v); v.validate[JsArray] })
))
println(result2) 
// {"a":[1]} - same value as in pick!
// JsError(List((//val(0),List(JsonValidationError(List(error.expected.jsarray),WrappedArray()))))

Теперь мы знаем, что это объект, так что давайте попробуем прикоснуться к нему.

val result3 = js.transform((__ \\ "val")(0).json.update(Reads.of[JsObject]))
println(result3)
// java.lang.RuntimeException: expected KeyPathNode

Проверим реализацию обновления: https://github.com/playframework/play-json/blob/2.6.9/play-json/shared/src/main/scala/play/api/libs/json/JsConstraints.scala#L85-L94

Это в основном:

  1. читает (с дополнительным преобразованием) значение, идентифицированное путем от корневого объекта
  2. создает объект только с этим путем и значением
  3. применяет JsObject.deepMerge к корневому объекту и объекту, содержащему значение

Метод JsPath.createObj, используемый в 2), может обрабатывать пути, указанные только ключами, но не индексами. Кажется, что невозможно изменить элементы вложенных массивов в play-json, по крайней мере, из коробки.

Между тем в цирке: https://scastie.scala-lang.org/wRLs7O72ScyOmcMyiTU5uw

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