-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
125 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"results": [ | ||
{ | ||
"id": 306, | ||
"name": "First Company", | ||
"branches": [ | ||
{ | ||
"id": 4191, | ||
"city": "Seattle", | ||
"customers": [ | ||
{ | ||
"id": 446, | ||
"name": "Big Tech 1" | ||
}, | ||
{ | ||
"id": 447, | ||
"name": "Big Tech 2" | ||
} | ||
] | ||
}, | ||
{ | ||
"id": 4192, | ||
"city": "Oakland", | ||
"customers": [ | ||
{ | ||
"id": 448, | ||
"name": "Health Tech 1" | ||
}, | ||
{ | ||
"id": 449, | ||
"name": "Health Tech 2" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
] | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# Unroll | ||
|
||
```jq | ||
[leaf_paths as $path | { | ||
"key": $path | map(tostring) | join("_"), | ||
"value": getpath($path) | ||
}] | from_entries | ||
``` | ||
|
||
```console | ||
$ cat data/nested.json|jq '[leaf_paths as $path | { | ||
"key": $path | map(tostring) | join("_"), | ||
"value": getpath($path) | ||
}] | from_entries | ||
' | ||
{ | ||
"server_atx_user": "annie", | ||
"server_atx_port": 22, | ||
"storage_nyc_user": "nntrn", | ||
"storage_nyc_port": 22 | ||
} | ||
``` | ||
|
||
```jq | ||
def categorize: | ||
# Returns "object", "array" or "scalar" to indicate the category | ||
# of the piped element. | ||
if type == "object" then "object" | ||
elif type == "array" then "array" | ||
else "scalar" | ||
end; | ||
def pluck($category): | ||
# Plucks the children of a particular category from piped element. | ||
if categorize != "object" | ||
then empty | ||
else to_entries[] | ||
| select(.value | categorize == $category) | ||
| .value | ||
end; | ||
def split: | ||
# Splits the piped element's children into arrays, scalars, and objects | ||
# and returns a meta object containing the children seperated by these | ||
# keys. If the piped element is a scalar or array, this does not look | ||
# at the children, but just returns that element in the meta object. | ||
if categorize == "scalar" then { objects: [], arrays: [], scalars: [.] } | ||
elif categorize == "array" then { objects: [], arrays: [.], scalars: [] } | ||
else { objects: [pluck("object")], arrays : [pluck("array")], scalars: [pluck("scalar")] } | ||
end; | ||
def unwrap: | ||
# Unwraps an array recursively, until the elements of the returned array | ||
# are either scalars or objects but not arrays. If piped element is not | ||
# an array, returns the element as is. | ||
if type != "array" then . | ||
elif length == 0 then empty | ||
else .[] | unwrap | ||
end; | ||
def extract($category): | ||
# Extracts the elements of a particular category from the piped in array. | ||
# If the piped in element is not an array, this fn acts as filter to | ||
# only return the element if it is of the desired category. | ||
unwrap | select(.| categorize == $category); | ||
def unroll: | ||
# Unrolls the passed in object recursively until only scalars are left. | ||
# Returns a row for each leaf node of tree structure of the object and | ||
# elements of the row would be all the scalars encountered at all the | ||
# ancestor levels of this left node. | ||
. | .result += .state.scalars | ||
| .state.objects += [.state.arrays | extract("object")] | ||
| .state.objects += [.state.arrays | extract("scalar")] | ||
| if (.state.objects | length == 0 ) | ||
then .result | ||
else ({ data : .state.objects, | ||
state: .state.objects[] | split, | ||
result: .result | ||
} | unroll) | ||
end; | ||
def unrolls($data): { data: $data, state: $data| split, result: [] } | unroll ; | ||
def unrolls: unrolls(.); | ||
``` |