Suppose we've got the following set-up (I'm using circe-literal for convenience, but your Json
values could come from anywhere):
import io.circe.Json, io.circe.literal._
val a1: Json = json"""[{"id": 1}, {"id": 2}, {"id": 3}]"""
val a2: Json = json"""[{"id": 4}, {"id": 5}, {"id": 6}]"""
Now we can combine them like this:
for { a1s <- a1.asArray; a2s <- a2.asArray } yield Json.fromValues(a1s ++ a2s)
Or:
import cats.std.option._, cats.syntax.cartesian._
(a1.asArray |@| a2.asArray).map(_ ++ _).map(Json.fromValues)
Both of these approaches are going to give you an Option[Json]
that will be None
if either a1
or a2
don't represent JSON arrays. It's up to you to decide what you want to happen in that situation .getOrElse(a2)
or .getOrElse(a1.deepMerge(a2))
might be reasonable choices, for example.
As a side note, the current contract of deepMerge
says the following:
Null, Array, Boolean, String and Number are treated as values, and values from the argument JSON completely replace values from this JSON.
This isn't set in stone, though, and it might not be unreasonable to have deepMerge
concatenate JSON arrays—if you want to open an issue we can do some more thinking about it.