I have the following JSON
Original Data
{
"myValues": [
{
"filterableValue": "x",
"something": "else"
},
{
"filterableValue": "y",
"another key": "another value"
},
{
"filterableValue": "z"
}
],
"foo": "bar"
}
Using JQ I want to add a key value pair to the first (or all) entries in the myValues
array, that have the filterableValue=="y"
. The position/index of these entries inside the myValues
array is arbitrary.
Expected Output
The result should have the same structure (still contain both foo
and myValues
) but have a modified entry where filterableValue=="y"
.
{
"myValues": [
{
"filterableValue": "x",
"something": "else"
},
{
"filterableValue": "y",
"another key": "another value",
"this": "has been added" // <-- this is the only thing that changed
},
{
"filterableValue": "z"
}
],
"foo": "bar"
}
What I tried and why it failed
So far I managed to filter the respective array entry and set the value on the filtered output but didn't manage to keep the original structure AND modifiy a filtered entry.
My JQ that adds the "this":"has been added"
pair but does not contain the original structure is:
.myValues|map(select(.filterableValue=="y"))[0]|.this="has been added"
jqplay mwe
Question
How can I modify a filtered entry as above and contain the original structure?
CodePudding user response:
Enclose the whole selector on the LHS within parentheses:
(.myValues[] | select(.filterableValue == "y")).this = "has been added"
CodePudding user response:
First, let's cleanup
.myValues | map(select(.filterableValue=="y"))[0]
It's better written as
.myValues[] | select(.filterableValue=="y")
Not only is it shorter, it handles the case where there are 0 or 2 matches better.
Then, you just need to change ... |
to ( ... ) |=
.
( .myValues[] | select(.filterableValue=="y") ) |= ( .this = "has been added" )