Использование оптики Circe для изменения всех полей объекта или всех элементов массива - PullRequest
2 голосов
/ 24 июня 2019

Я пытаюсь изменить вложенную структуру JSON, используя Оптика Circe . Однако во всех примерах изменяется только одно поле внутри объекта с известным именем.

Что мне нужно сделать:

  • Предполагая, что ключ foo моего объекта содержит массив объектов, увеличивайте ключ counter в каждом из них.
  • Предполагая, что ключ bar моего объекта содержит объект, увеличивайте ключ counter в значениях, сопоставленных с каждым ключом в этом объекте.
  • Сохраните все остальные значения в объекте без изменений.

Пример:

{
  "foo": [
    {
      "counter": 1
    },
    {
      "counter": 2
    }
  ],
  "bar": {
    "three": {
      "counter": 3
    },
    "four": {
      "counter": 4
    }
  }
}

должно стать

{
  "foo": [
    {
      "counter": 2
    },
    {
      "counter": 3
    }
  ],
  "bar": {
    "three": {
      "counter": 4
    },
    "four": {
      "counter": 5
    }
  }
}

Поведение, когда типы объекта и его членов не соответствуют моим ожиданиям, не важно.

Я ожидаю что-то вроде этого:

val incrementCounterArray: Json => Json =
    root.foo.eachArrayItem.counter.modify(_ + 1)
val incrementCounterObject: Json => Json =
    root.bar.eachObjectValue.counter.modify(_ + 1)

но я не вижу каких-либо определений того, что было бы eachArrayItem или eachObjectValue в учебнике.

1 Ответ

2 голосов
/ 24 июня 2019

Правильный синтаксис:

val incrementCounterArray: Json => Json =
  root.foo.each.counter.int.modify(_ + 1)

val incrementCounterObject: Json => Json =
  root.bar.each.counter.int.modify(_ + 1)

Посмотрите пример в официальной документации circe-optics для получения более подробной информации:

...