I had the following json array:
{
"metric": {
"instance": "100.120.207.215:8081",
"job": "job1",
"error_code": "500"
},
"values": [
[
1665129206,
"128"
],
[
1665129236,
"129"
],
[
1665129266,
"130"
],
[
1665129296,
"135"
]
]
}
I want to get the difference between each array, looks like
1665129236,1
1665129266,1
1665129296,5
Please help on it. Thanks a lot.
CodePudding user response:
If the arrays fit your memory, you can make two copies, shift them one apart to each other, transpose and subtract:
.values | [.[:-1], .[1:]] | transpose[]
| "\(.[1][0]),\(map(.[1] | tonumber) | .[1]-.[0])"
Alternatively, you can use either foreach
or while
to iterate over a window of two adjacent items:
.values | foreach .[1:][] as $v ([null, .[0]]; .[1:] [$v];
"\(.[1][0]),\(map(.[1] | tonumber) | .[1]-.[0])"
)
.values | while(has(1); .[1:])[:2]
| "\(.[1][0]),\(map(.[1] | tonumber) | .[1]-.[0])"
Output:
1665129236,1
1665129266,1
1665129296,5
CodePudding user response:
Building on pmf's excellent answer:
.values[][1] |= tonumber
| [.values[1:], .values[:-1]]
| transpose[]
| [
first[0],
(map(last) | first-last)
]
| join(",")
Since all your values are numbers, the final join
filter could be replaced with @csv
.
CodePudding user response:
Here's a solution that uses a generic derivative
function that has already been used elsewhere on SO:
# Input: an array
# `delta` should be a non-negative integer, typically 1;
# p is the jq path expression to the quantity within an item, e.g. `.`
def derivative(delta; p):
. as $in
| [ range(delta; length) as $i
| .[$i]
| (p = ($in[$i] | p) - ($in[$i - delta] | p)) ];
.values |=
(map(.[1] |= tonumber)
| derivative( 1; .[1]))