Having the following json structure:
{
"outerDescription1": {
"innerDescription1": {
"otherProperties": 1,
"items": [
"arrayItem1",
"arrayItem2"
]
}
},
"outerDescription2": {
"innerDescription2": {
"otherProperties": 2,
"items": [
"arrayItem3",
"arrayItem4"
]
}
}
}
I would like to get the following result:
{
"item": "arrayItem1",
"outer": "outerDescription1",
"inner": "innerDescription1",
"otherProperties": 1
}
{
"item": "arrayItem2",
"outer": "outerDescription1",
"inner": "innerDescription1",
"otherProperties": 1
}
{
"item": "arrayItem3",
"outer": "outerDescription2",
"inner": "innerDescription2",
"otherProperties": 2
}
{
"item": "arrayItem4",
"outer": "outerDescription2",
"inner": "innerDescription2",
"otherProperties": 2
}
Assumption: there are many outerDescription
and innerDescription
keys and they are not known upfront.
Single level unroll is would be simple, but unrolling double-nested objects with different keys is a challenge to me.
The closest what I was able to get was:
jq "with_entries(.value = {outer: .key} + .value)[]"
which resulted in:
{
"outer": "outerDescription1",
"innerDescription1": {
"otherProperties": 1,
"items": [
"arrayItem1",
"arrayItem2"
]
}
}
{
"outer": "outerDescription2",
"innerDescription2": {
"otherProperties": 2,
"items": [
"arrayItem3",
"arrayItem4"
]
}
}
But right now, without knowing the next nested key name exactly, I am not able to unroll for a second time in the same way as outer
would be swallowed.
I am using JQ 1.6
3
Answers
You could use
path
to find the according paths, andgetpath
to retrieve their values:Demo
If you know the name of your
items
property, the following equivalent programs are quite readable:You could also use a function:
JSON does not care about key order in objects, but if – for whatever reason – you need to force a specific order, you append a final transformation. But this requires to list all keys again:
Output:
Here’s a straightforward solution using
to_entries
:Or, equivalently but without variables:
If the order of keys is important, you could (for example) add
an expression such as
{item, outer, inner, otherProperties}
.Addendum: To retain all the keys at the "otherProperties" level (apart from .items), you could tweak the solution above: