Last active
August 5, 2021 02:13
-
-
Save pkoppstein/5eac78d3e9618cfabd7d to your computer and use it in GitHub Desktop.
a commutative and associative operator for combining two JSON objects
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
# This gist defines a jq filter for combining two JSON objects by resolving conflicts | |
# in a way that is appropriate for mapping relational tables to objects. | |
# "combine" as defined here is both commutative and associative. | |
# Example: | |
# { "id": 123, "son": "Son1", "surname": "S"} | |
# | combine({ "id": 123, "son": "Son2", "surname": "S"}) | |
# produces: { "id": 123, "son": ["Son1",Son2], "surname": "S"} | |
# Combine two entities in an array-oriented fashion. | |
# If uniq is true, then pass the results of the following through unique: | |
# if both are arrays: a + b | |
# else if a is an array: a + [b] | |
# else if b is an array: [a] + b | |
# else [a, b] | |
def aggregate(a;b;uniq): | |
if uniq then aggregate(a; b; false) | unique | |
elif (a|type) == "array" then | |
if (b|type) == "array" then a + b | |
else a + [b] | |
end | |
else | |
if (b|type) == "array" then [a] + b | |
else [a, b] | |
end | |
end; | |
# Combine . with obj using aggregate/3 for shared keys whose values differ | |
def combine(obj): | |
. as $in | |
| reduce (obj|keys|.[]) as $key | |
($in; | |
if .[$key] == obj[$key] then . | |
else setpath([$key]; | |
aggregate( $in|getpath([$key]); obj|getpath([$key]); true ) ) | |
end ) ; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment