DEV Community

Josh Branchaud
Josh Branchaud

Posted on • Edited on

Reduce a JSON Object to just Entries of a Specific Type with jq

A large JSON object can be hard to work with when it has tons of top-level fields that you have to wade through. One way to make that data exploration more approachable is to reduce what is there — filtering by type is a great starting point. Here is how I do that with the jq utility.

Let's say I want to start with a view of the JSON that is restricted to just the field whose values are of type array.

To do this, I need to use a couple different jq helper functions.

The select function produces the input value as the output if the given boolean expression is true. This is where I can do the type check. In this case, does the type of .value match "array".

select(.value | type | match("array"))
Enter fullscreen mode Exit fullscreen mode

Combining that select with map, I can filter an array to just those values that match my condition.

map(select(.value | type | match("array")))
Enter fullscreen mode Exit fullscreen mode

Because map expects an array and I'm starting with an object, I need to open up with a to_entries call. This turns the object into an array of .key and .value pairs. Hence, the .value that appears inside the select. Putting a from_entries on the other end of the map will take the reduced array of key-value pairs and turn it back into an object.

some_obj | to_entries | map(...) | from_entries
Enter fullscreen mode Exit fullscreen mode

Putting this all together:

jq '. | to_entries | map(select(.value | type | match("array"))) | from_entries' data.json
Enter fullscreen mode Exit fullscreen mode

There is a less verbose way to do the above. The to_entries and from_entries can be collapsed into a with_entries that replaces the map call.

jq '. | with_entries(select(.value | type | match("array"))' data.json
Enter fullscreen mode Exit fullscreen mode

with_entries(foo) is a shorthand for to_entries | map(foo) | from_entries, useful for doing some operation to all keys and values of an object.

This can be extended to select for multiple types with a little conditional logic like so:

jq '. | with_entries(select((.value | type) == "array" or (.value | type) == "object"))' data.json
Enter fullscreen mode Exit fullscreen mode

That's just a drop in the bucket for how jq can be used to explore JSON data files.

With this tool being so general-purpose and having so many utilities, workflows like this one are where things get most interesting. Share your jq workflows with me in the comments below 👇

If you enjoyed this post, consider joining my newsletter or following me on twitter. If this helped you or you have a question, feel free to drop me note wherever. I'd love to hear from you!

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs