Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge several json arrays in circe

Tags:

json

scala

circe

Let's say we have 2 json arrays. How to merge them into a single array with circe? Example:

Array 1:

[{"id": 1}, {"id": 2}, {"id": 3}]

Array 2:

[{"id": 4}, {"id": 5}, {"id": 6}]

Needed:

[{"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 6}]

I've tried deepMerge, but it only keeps the contents of the argument, not of the calling object.

like image 623
Haspemulator Avatar asked Apr 14 '16 13:04

Haspemulator


People also ask

How do I combine two JSON responses?

We can merge two JSON objects using the putAll() method (inherited from interface java. util. Map) in the below program.

What is merge JSON?

json-merge is a library allowing you to merge two json files for the JVM written in Kotlin. It currently supports two modes for merging arrays and objects.


1 Answers

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.

like image 80
Travis Brown Avatar answered Oct 06 '22 09:10

Travis Brown