Remove key from array of json using circe

1.6k Views Asked by At

I have a json as:

[
  {
    "a": "a",
    "b": "b",
    "c": "c"
  },
  {
    "a": "a1",
    "b": "b1",
    "c": "c1"
  }
]

Now, I want to delete the key for c. So the result would be:

[
  {
    "a": "a",
    "b": "b"
  },
  {
    "a": "a1",
    "b": "b1"
  }
]

I am using circe, what I have done until now is:

parse(entityAs[String]) match {
  case Right(value) =>
    val json = value.hcursor
    val result = json.downArray.downField("c").delete
    println(">>>>>>>>>>>>>>>>>")
    println(result.right.as[List[Json]])
         
  case Left(_) =>
}

There is some problem with this line

val result = json.downArray.downField("c").delete

What would be the correct line to delete the key c and then convert it back to list of json using circe?

1

There are 1 best solutions below

0
On

delete returns a cursor at the position of the thing the element was deleted from. You want to get back the whole document, you can navigate back to the top with top. You'll get back the modified document. Given

val doc = parse(entityAs[String])

going to the top with

doc.hcursor.downArray.downField("c").delete.top

will give you

Some([
  {
    "a" : "a",
    "b" : "b"
  },
  {
    "a" : "a1",
    "b" : "b1",
    "c" : "c1"
  }
])

But as I understand, you want to remove the next "c" too. That would be

doc.hcursor.downArray.downField("c").delete.right.downField("c").delete.top

or, to delete them all

def removeCs(element: ACursor): ACursor = {
  val deleted = element.downField("c").delete
  val focus = deleted.success.getOrElse(element)
  focus.right.success match {
    case Some(next) => removeCs(next)
    case None => focus
  }
}

removeCs(doc.hcursor.downArray).top