spray-json icon indicating copy to clipboard operation
spray-json copied to clipboard

Add support of merging JsObject's

Open ataraxer opened this issue 10 years ago • 3 comments

I believe that a simple fields Map's concatenation of two objects should achieve the expected behaviour.

Resolves #72.

ataraxer avatar Jan 15 '15 21:01 ataraxer

LGTM

Twisterius avatar Oct 05 '15 15:10 Twisterius

Was this ever merged? Is there any other way to merge JsObjects in the current mainline?

johanatan avatar Apr 06 '16 22:04 johanatan

I'm using the following, which fits my needs better than a field replacement:

import spray.json.JsValue
import scala.annotation.tailrec

package object util {
  implicit class PimpedJsObject(obj: JsObject) {
    def merge(obj2: JsValue): JsObject = {

      def mergeLoop(val1: JsValue, val2: JsValue): JsValue = {
        (val1, val2) match {
          case (obj1: JsObject, obj2: JsObject) => {
            val map1 = obj1.fields
            val map2 = obj2.fields
            val diff1 = map1.keySet.diff(map2.keySet)
            val diff2 = map2.keySet.diff(map1.keySet)
            val intersect = map1.keySet.intersect(map2.keySet)
            val merged = intersect.map { key =>
              val val1 = map1(key)
              val val2 = map2(key)
              (val1, val2) match {
                case (val1: JsObject, val2: JsObject) => (key -> mergeLoop(val1, val2))
                case (_, val2) => (key -> val2)
              }
            }.toMap
            val distinct = map1.filter(t => diff1(t._1)) ++ map2.filter(t => diff2(t._1))
            JsObject(distinct ++ merged)
          }
          case (_, val2) => val2
        }
      }
      mergeLoop(obj, obj2).asJsObject
    }
  }
}```

rleibman avatar Sep 11 '17 21:09 rleibman