I have two simple JSON objects, I’m trying to add a single object from a Bash variable newValArr
in order of the corresponding objects to the masterfile.json
. They appear as following:
newValArr
[{ "firstValue": "foo", "secondValue": "bar"},
{ "firstValue": "baz", "secondValue": "qux"},
...
]
masterfile.json
{
"value": [
{
"id": "abc",
"properties": {
"blah": "stuff"
}
},
{
"id": "def",
"properties": {
"blah": "morestuff"
}
},
...
]
}
I’ve created the following in Bash that adds the firstValue
and secondValue
object in the intended spot in the value
array of objects, here is the script:
jq --argjson newvalues "${newValArr}" '.value[].properties.newObject += $newvalues[0]' masterfile.json > newoutput.json
And here is the current JSON output:
newoutput.json
{
"value": [
{
"id": "abc",
"properties": {
"blah": "stuff",
"newObject": {
"firstValue": "foo",
"secondValue": "bar"
}
}
},
{
"id": "def",
"properties": {
"blah": "otherstuff",
"newObject": {
"firstValue": "foo",
"secondValue": "bar"
}
}
},
...
]
}
With the desired output being:
{
"value": [
{
"id": "abc",
"properties": {
"blah": "stuff",
"newObject": {
"firstValue": "foo",
"secondValue": "bar"
}
}
},
{
"id": "def",
"properties": {
"blah": "otherstuff",
"newObject": {
"firstValue": "baz",
"secondValue": "qux"
}
}
},
...
]
}
The problem obviously is that the same newValArr
object is being placed into every single newObject
as we’re continually referencing the same index. If we don’t specify the index, then all the newValArr
objects will be placed into each newObject
, and I’m not quite sure if it’s even possible to iterate through the indexes in JQ like we would in Bash using newValArr[@]
for example so that each index could be assigned in order. Is this possible in JQ? Or must an entirely different method be used?
The two JSON’s will always have the same number of objects, in the same order, no need to worry about that.
I’ve looked into implementing this using to_entires, however it doesn’t seem compatible with what I’m trying to accomplish.
2
Answers
One way to do it is create a range of all the indexes of the arrays and build a new object by combining the corresponding elements:
outputs
Or another approach that uses
transpose
to zip the two arrays together and then merges them:You could use
to_entries
which, when applied to an array, generates indices in the.key
field, which then can be used to index into the imported variable. Then, justmap
over the result array to construct your final objects.