2

I am trying to modify a nested JSON structure using Circe's optics. However, all the examples are only modifying a single field within the object with the known name.

What I need to do:

  • Assuming foo key of my object contains an array of objects, increment the counter key in each of those.
  • Assuming bar key of my object contains an object, increment the counter key in values mapped to each key in that object.
  • Keep all the other values in the object intact.

Example:

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

should become

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

The behavior when the types of the object and its members are not what I expect is not important.

I expect something like this:

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

but I don't see any definitions for what would be eachArrayItem or eachObjectValue in the tutorial.

Koterpillar
  • 7,883
  • 2
  • 25
  • 41

1 Answers1

2

The correct syntax is

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

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

Have a look at the example in the official circe-optics documentation for more details:

Harald Gliebe
  • 7,236
  • 3
  • 33
  • 38