Reputation: 1011
I have a JSON file like this
{
"hierarchy": {
"structure": {
"card_11001": [
"addCard_4111"
],
"container_11006": [
"mainContainer_11007",
"subContainer_10016"
],
"mainContainer_11007": [
"paymentMethodList_10001"
],
"orderWrap_10012": [
"orderSummary_10005"
],
"paymentMethodList_10001": [
"card_11001",
"placeOrder_10013"
],
"root_10000": [
"payNotice_11011",
"payNotice_10020",
"container_11006",
"placeOrderResultAction_10004"
],
"subContainer_10016": [
"orderWrap_10012",
"footer_10014"
]
}
}
}
And I want to insert
"offline_11018": [
"instruction_908",
"checkboxList_11019"
]
Between "mainContainer_11007"
and "orderWrap_10012"
so the result I want should look like this:
{
"hierarchy": {
"structure": {
"card_11001": [
"addCard_4111"
],
"container_11006": [
"mainContainer_11007",
"subContainer_10016"
],
"mainContainer_11007": [
"paymentMethodList_10001"
],
"offline_11018": [
"instruction_908",
"checkboxList_11019"
],
"orderWrap_10012": [
"orderSummary_10005"
],
"paymentMethodList_10001": [
"card_11001",
"placeOrder_10013"
],
"root_10000": [
"payNotice_11011",
"payNotice_10020",
"container_11006",
"placeOrderResultAction_10004"
],
"subContainer_10016": [
"orderWrap_10012",
"footer_10014"
]
}
}
}
All I know is that I can only append it to the end of file with
jq --raw-output '.hierarchy.structure + {"offline_11018": ["instruction_908","checkboxList_11019"]}'
But that's not what I want, I want to insert it between two other keys. How can I do it with the jq command?
Upvotes: 4
Views: 2226
Reputation: 116967
The simplest approach would be to use to_entries
to convert .hierarchy.structure
into an array, perform the insertion, and then use from_entries
to reconstitute the object, along the lines of:
.hierarchy.structure |= (to_entries
| ... as $ix
| .[:$ix] + ($x | to_entries) + .[$ix:]
| from_entries)
The above sketch of course would need to be modified if it is possible that the item defining the insertion point cannot be found.
indexof/1
Here's a useful "def" for finding the least index for which some condition holds:
# If the input is an array, emit the least index, $i,
# for which `.[$i]|f` is truthy, otherwise emit null.
# Works similarly if the input is a JSON object.
def indexof(f):
label $out
| foreach .[] as $x (null; .+1;
if ($x|f) then (.-1, break $out) else empty end) // null;
indexof
Putting the above pieces together:
{"offline_11018": [ "instruction_908", "checkboxList_11019" ]} as $x
| .hierarchy.structure |= (to_entries
| (1 + indexof( .value | index("mainContainer_11007") )) as $ix
| .[:$ix] + ($x | to_entries) + .[$ix:]
| from_entries)
Upvotes: 2