Knows Not Much
Knows Not Much

Reputation: 31526

How to parse nested Json Arrays with Circe Optics

I read the example given by the Circe docs using Circe Optics. The example in the docs is pretty straight forward because the path to the node is pretty easy to find.

In my case the json looks like

import io.circe._, io.circe.parser._

val json = """[["a",{"entity":["foo"]}],["b",{"entity":["bar"]}]]"""

This is a valid json and I can parse is using parse(json)

But how do I write a lens so that I extract all "foo", "bar".

Upvotes: 2

Views: 1445

Answers (1)

Travis Brown
Travis Brown

Reputation: 139028

If you want the fancy JsonPath style, you can use each to select every matching member of a JSON array, so your path could look like this:

import io.circe.optics.JsonPath

val entities = JsonPath.root.each.each.entity.each.string

And then supposing you have the following Json value:

import io.circe.jawn.parse

val Right(json) = parse("""[["a",{"entity":["foo"]}],["b",{"entity":["bar"]}]]""")

You could use the Traversal path like this:

scala> entities.getAll(json)
res0: List[String] = List(foo, bar)

scala> entities.modify(_ * 2)(json).noSpaces
res1: String = [["a",{"entity":["foofoo"]}],["b",{"entity":["barbar"]}]]

scala> entities.set("___")(json).noSpaces
res2: String = [["a",{"entity":["___"]}],["b",{"entity":["___"]}]]

You could also construct the path explicitly, but it'd involve a lot more code.

Upvotes: 6

Related Questions