使用Circe光学器件修改对象的所有场或阵列的所有项

时间:2019-06-24 03:46:43

标签: json scala circe

我正在尝试使用Circe's optics修改嵌套的JSON结构。但是,所有示例都仅修改对象中具有已知名称的单个字段。

我需要做什么:

  • 假设我对象的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)

但是我在本教程中没有看到eachArrayItemeachObjectValue的定义。

1 个答案:

答案 0 :(得分:2)

正确的语法是

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

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

有关更多详细信息,请查看官方circe-optics documentation中的示例: