JQ with_entries Explained
Getting the length of values for each key in an object
with_entries(.value = (.value | length))
If different operations need to be performed on each key, then something like the following might work:
with_entries( .value = if .value|type == "array" then .value | length else .value end )
In the above operations, each character used in the jq expression has a purpose. For example, if the part of the expression (.value | length)
lacked the brackets, it would mean something else entirely and the expression may fail.
The with_entries
function takes an object as input. For each entry|key|property in that object, it creates a new object that has two keys. One is called key and the other is called value.
Inverting the order of key and values in an object
Let's say we have an JSON object that looks like this:
What we want is to invert keys and values. This means, we want to make the keys be values and the values be keys.
This the expression that does that for us:
. | to_entries | map({key:.value|tostring,value:.key}) | from_entries
What's happening here?
The to_entries
operation splits an object into an array for each key.
The map
operations performs the transformation for us to build a new object. The expression {key:.value|tostring,value:.key}
is an object builder. It builds a new object with that has two properties, key and value. The operation we want to perform are on the right hand side of :
. We will call this output the transformed object.
Finally, the from_entries
function takes an array of objects with properties key and value, and builds an array where each object has key denoted by the "key" property in the object, and the value of that key is the "value" property of the input transformed object.
The with_entries
operation provides syntactic sugar around this common transformation operation. It can be succinctly written like this:
with_entries({key:.value|tostring,value:.key})