How to filter an array of objects based on values in an inner array with jq?
How to filter an array of objects based on values in an inner array with jq?
Are you struggling to filter an array of objects in jq based on values in an inner array? Fret not! In this blog post, we'll explore a common issue and provide you with easy, step-by-step solutions to help you tackle this problem. 🧩
The Problem
Let's start by examining the specific problem at hand. We have an array of objects with the following structure:
[
{
"Id": "cb94e7a4...",
"Names": [
"condescending_jones",
"loving_hoover"
]
},
{
"Id": "186db739...",
"Names": [
"foo_data"
]
},
{
"Id": "a4b7e6f5...",
"Names": [
"jovial_wozniak"
]
},
{
"Id": "76b71c49...",
"Names": [
"bar_data"
]
}
]
Our goal is to construct a filter using jq that returns all objects whose Id
does not contain the string "data" in the inner Names
array. The expected output, when applying the filter to the provided input, would be:
cb94e7a4...
a4b7e6f5...
The Solution
To achieve the desired filtering, we need to correctly use the select
filter in jq. 🕵️♀️
Here's a step-by-step solution:
Start by applying the
select
filter to each object in the array. We want to select objects where none of the names in theNames
array contain the string "data". The filter below accomplishes this:select( any(.Names[]; contains("data")|not) )
Next, we want to extract only the
Id
value from the selected objects. We can use the map function along with the.Id
selector:map(.Id)
Finally, we want to join the resulting array of
Id
values into a newline-separated string. You can achieve this using thejoin
function with the newline character as the separator:join("\n")
Putting it all together, the complete jq filter would look like this:
[
{
"Id": "cb94e7a4...",
"Names": [
"condescending_jones",
"loving_hoover"
]
},
{
"Id": "186db739...",
"Names": [
"foo_data"
]
},
{
"Id": "a4b7e6f5...",
"Names": [
"jovial_wozniak"
]
},
{
"Id": "76b71c49...",
"Names": [
"bar_data"
]
}
]
| select( any(.Names[]; contains("data")|not) )
| map(.Id)
| join("\n")
When you run this filter against the provided input, you'll get the desired output:
cb94e7a4...
a4b7e6f5...
Conclusion
Filtering an array of objects based on values in an inner array can be a tricky task, but with the right approach, it becomes a breeze. In this guide, we've shown you how to use jq to accomplish this task step-by-step. Remember, applying the select
filter, extracting the desired values, and joining them appropriately are key.
Now it's your turn! Give it a try with your own data and let us know how it goes. If you encounter any difficulties or have any questions, feel free to leave a comment below. Happy filtering! 🎉😊