Search code examples
jsonscalascala-catscirce

Scala, Circe - how to check if json contains keys with different values?


I have a json which includes to similar fields:

{
  "newData": {
    "data": {
      "field1": "value1",
      "field2": value2,
      "field3": "value3"
    }
  }
  "oldData" :{
    "data": {
      "field1": "value1",
      "field3": "someValue"
    }
  }
}

Now I would like to compare newData with oldData. If newData include some new fields which are not in oldData I want add them to Set. Also if newData and oldData have same field, but with different values I also want to add them to Set. If they are same I want to ignore.

I tried to do it with circe like this:

val newData = json.newData
val oldData = json.oldData
val result = newData.hcursor.keys.toSet
.filterNot(oldData.hcursor.keys.toSet)

And it works ok if newData have some other fields then oldData. But it does not work if both of them have same field with other values. I do not know how I could compare values of same key in both jsons and if they are different, add them to set. How should I change my code to include it?


Solution

  • You can ensure that both are JsonObjects and then pick all the keys of the new record and check whenever that key existed in the old record or not, and if it did exist then ensure that its contents are different.

    import io.circe.JsonObject
    
    def findFieldsWithDifferences(oldData: JsonObject, newData: JsonObject): Set[String] =
      newData.toList.collect {
        case (newKey, newValue) if oldData(key = newKey).forall(_ != newValue) =>
          newKey
      }.toSet
    

    You can see the code running here.