I have a json array of hundreds of objects and each object contains (among many other fields) two arrays like this and a status indicator:
"searchMetaData": {"rrStandard": ["XYZ5.1","6.3"],"ccStandard": ["46d45a68-a930","8cd1dc9a-d6a2"],"status": "complete"}
For any object where status is "complete", I want to look at the rrStandard array and remove any array elements that don’t start with XYZ (ie, it would remove "6.3"). But I also need to remove the corresponding element in the ccStandard array, but that array doesn’t have patterns I can match on, so I think I would have to remove based on a corresponding index number.
Is there a way with jq to remove the "6.3" from rrStandard, somehow remember what its index was (e.g. 1) and then remove the element at that same index (e.g. index 1) in the ccStandard array as well?
In the production case, these arrays will sometimes have more than just 2 values in the arrays, but the number of elements will match between the two. So, it may be that I need to remove elements 1,2, and 3 across both arrays for example.
I’m new to jq and have (I think) figured out how to find and remove the "6.3" from rrStandard but from there I’m lost.
Here is what I have so far to simply find and delete the "6.3" from rrStandard:
.[].searchMetaData |= if(.status == "complete") then (del(.rrStandard[] | select(startswith("XYZ") | not))) else . end
2
Answers
One way would be to use
to_entries
to get an array of indices and values, filter for the values and use the indices to remove from both arrays:Demo
Another way would be to
reduce
over thekeys
in one array, and delete from both arrays if there is a match. The iteration is inreverse
order to not affect higher indices after lower ones have been deleted:Demo
Yet another way would be to coordinate both arrays and
transpose
them twice. After the first one, the elements line up, and those matching can be deleted in one go:Demo
You’re looking for something like this: