6

What I'd like to do, is having field descriptor defined as field1.field2[1].field3, access value two of json:

{
  "field1": {
    "field2": [
      {
        "field3": "one"
      },
      {
        "field3": "two"
      }
    ]
  }
}

I know I can do that using applyDynamic and root.field1.field2.index(1).field3, but is there a way to create such a lens using a string?

Bartek Andrzejczak
  • 1,292
  • 2
  • 14
  • 27
  • 2
    applyDynamic accept String – WeiChing 林煒清 Mar 23 '18 at 14:10
  • 4
    Thank you @WeiChingLin for the pointer! - this is the correct answer. In fact, `selectDynamic` works a little nicer, eg. `root.selectDynamic("some.path").string.getOption(jsonObj)` (where you can switch out 'string' to be one of the other types in [io.circe.optics.JsonPath](https://github.com/circe/circe-optics/blob/master/optics/src/main/scala/io/circe/optics/JsonPath.scala), such as boolean or int, etc. The import you need is `io.circe.optics.JsonPath._` – Barry O'Neill Apr 18 '19 at 13:54
  • `root.selectDynamic("some.path")` does not work. I do not see anything in JsonPath that would allow you to do such a query. Instead `"some.path".split(".").foldLeft(root)((p,f) => p.selectDynamic(f)).string.getOption(jsonObject)` works. Or without optics: `"some.path".split(".").foldLeft[ACursor](json.hcursor)((p,f) => p.downField(f)).as[String].toOption` – Tobi Feb 21 '22 at 12:43
  • `"some.path".split(".")` should be `"some.path".split("\\.")` or `"some.path".split('.')` – Tobi Feb 22 '22 at 01:55

0 Answers0