I have a input like below which just has stageIds, along with their submit and completion time in unix time seconds
[
{
"stageId": 1,
"submitTime_epoch_secs": 5,
"completionTime_epoch_secs": 10
},
{
"stageId": 2,
"submitTime_epoch_secs": 15,
"completionTime_epoch_secs": 17
},
{
"stageId": 3,
"submitTime_epoch_secs": 22,
"completionTime_epoch_secs": 30
}
]
desired output is below, where each stageId, submit, and completion times are compared with previous and next and the delay is added as another key/val per element.
[
{
"stageId": 1,
"submitTime_epoch_secs": 5,
"completionTime_epoch_secs": 10,
"delayTillNextStageSubmit",5
"delayFromPrevStageComplete",null
},
{
"stageId": 2,
"submitTime_epoch_secs": 15,
"completionTime_epoch_secs": 17,
"delayTillNextStageSubmit",12
"delayFromPrevStageComplete",5
},
{
"stageId": 3,
"submitTime_epoch_secs": 29,
"completionTime_epoch_secs": 30,
"delayTillNextStageSubmit",null
"delayFromPrevStageComplete",12
}
]
here the stageId 1 delayTillNextStageSubmit is difference between stageId 2 submitTime and stageId 1 completion time, 15 - 10 = 5.
is this possible with jq?
I am new to jq, so don't know how to solve this
CodePudding user response:
Here is one way:
reduce range(length - 1) as $i (.;
.[$i].delayTillNextStageSubmit = .[$i 1].submitTime_epoch_secs - .[$i].completionTime_epoch_secs
) |
reduce range(1; length) as $i (.;
.[$i].delayFromPrevStageComplete = .[$i - 1].delayTillNextStageSubmit
)
CodePudding user response:
Here is a derivative
method for this kind of task:
# Input: an array
# $delta is the lag (e.g. 1) or lead (e.g. -1)
# p1 is the jq path expression to the quantity within "this" item
# p2 is the jq path expression to the quantity within "that" item
# q is the jq path expression for the delta value
def derivative($delta; p1; p2; q):
. as $in
| length as $length
| [ range(0; $length) as $i
| .[$i]
| if 0 <= $i and $i < $length and 0 <= ($i - $delta) and ($i - $delta) < $length
then q = ($in[$i] | p1) - ($in[$i - $delta] | p2)
| q |= (if $delta > 0 then . else - . end)
else q = null
end ];
If $data
holds your data, then based on my understanding of the question, you would invoke it like this:
$data
| derivative(-1; .completionTime_epoch_secs; .submitTime_epoch_secs; .delayTillNextStageSubmit)
| derivative( 1; .submitTime_epoch_secs; .completionTime_epoch_secs; .delayFromPrevStageComplete)
Please note there seems to be an inconsistency between the input and output for stageId 3 in your example: "submitTime_epoch_secs" is shown as 22 and then as 29.