Created
June 16, 2021 20:32
-
-
Save ShahOdin/e30f0f019cdf6ce9e38e7e7537ea5cd9 to your computer and use it in GitHub Desktop.
deep merge but respect arrays
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private def extractNestedArray( | |
json: Json | |
): Option[(NonEmptyList[String], Vector[Json])] = { | |
def extractNestedArrayInternal( | |
acum: List[String], | |
json: Json | |
): Option[(NonEmptyList[String], Vector[Json])] = | |
json.arrayOrObject( | |
or = None, | |
jsonArray = jsons => NonEmptyList.fromList(acum).map(_ -> jsons), | |
jsonObject = _.toList.headOption.flatMap { | |
case (k, v) => | |
extractNestedArrayInternal(k :: acum, v) | |
} | |
) | |
extractNestedArrayInternal(Nil, json).map { | |
case (keys, jsons) => | |
keys.reverse -> jsons | |
} | |
} | |
private def concatArrayValueAtPath( | |
json: Json, | |
path: NonEmptyList[String], | |
newValues: Vector[Json] | |
): Option[Json] = | |
path | |
.foldLeft[ACursor]( | |
json.hcursor | |
) { | |
case (cursor, fieldName) => | |
cursor.downField(fieldName) | |
} | |
.withFocusM( | |
_.asArray | |
.map(_.appendedAll(newValues)) | |
.map(Json.fromValues) | |
) | |
.flatMap(_.top) | |
implicit class jsonOps(json: Json) { | |
def deepMergeAndConcatArrays(that: Json): Json = | |
extractNestedArray(that) | |
.flatMap { | |
case (arrayPath, those) => | |
concatArrayValueAtPath( | |
json = json, | |
path = arrayPath, | |
newValues = those | |
) | |
} | |
.getOrElse( | |
json.deepMerge(that) | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
extracted from https://gist.github.com/ShahOdin/cb16b6989ffc382d9962075fa7dba243 where I was trying to unflatten a json.