Exploring JSON with interactive jq
I often use ijq, or "interactive jq", to explore JSON, and also to improve my jq fu, because it gives me immediate visual feedback. Here's an example.
There's a wrapper around jq
called ijq (short for "interactive jq") which is a bit like a REPL in that it affords immediate feedback. It's a lovely program, and I use it a lot.
Yesterday I shared a short video of an example of how it can be used to explore a JSON dataset and I thought I'd give that example a more permanent home here on the blog.
(There's an asciinema version of this too).
In practising a little jq
, I thought I'd use it to find out the most common city in the Customers and Suppliers by Cities entityset in the V4 Northwind service.
This is the invocation I ended up with:
.value
| group_by(.City)
| map([length, first.City])
| sort_by(.[0])
| reverse
| first[1]
Here's a brief breakdown of the invocation I ended up with:
.value
gives me the entire array of objects in the dataset, each one of which represents a customer or supplier in a citygroup_by(...)
collects array elements together that have the same path expression specified (in this case theCity
property), producing an array of arraysmap(...)
is much likemap
in other languages, in that it will apply the function or filter given to the input array, producing a new array[length, first.City]
uses the array constructor ([...]
) to produce an array of two elements, the first being the length of the input (the inner array containing the same-city grouped objects) and the value of theCity
property for thefirst
element in that array*sort_by(...)
sorts the input array (which is now the one with length-and-city name elements) by the first item (.[0]
), i.e. by the lengthreverse
simply reverses the order of the items of the arrayfirst[1]
then this picks the second item ([1]
) of the first element, which after the reverse-sort will be the length-and-city pair with the highest length
*during the interactive session, I'd just guessed that there would be a first
function, and there was!
For those of you wondering, I deliberately chose to reverse the list before picking out the first element, so the element would be at the top and therefore visible in ijq
's output window:
| sort_by(.[0])
| reverse
| first[1]
But I could have just as well done this:
| sort_by(.[0])
| last[1]
As a kind fellow rightly pointed out in the comments to my previous post JSON object values into CSV with jq - TIMTOWTDI, or "there is more than one way to do it", an adage from the Perl community.