How can I count objects in jq (not in an array)

Viewed 879

I have some json input that comes as a list of objects (not as a json array) like, for which I want to count the number of active, and the number of inactive:

{
  "key" : "state",
  "value" : "active"
}
{
  "key" : "state",
  "value" : "active"
}
{
  "key" : "state",
  "value" : "active"
}
{
  "key" : "state",
  "value" : "inactive"
}

I want to transform using only JQ (in fact it will be handled by jackson-jq in java code, so I can not use some shell tricks).

I tried many things, like select(.value == "active") | length to get the number of active, but it is always handle object per object. Even when using reduce, it is always handled object per object.

Example of output is :

2
2
2

(I have 3 objects with 2 fields that match value="active)

The output that I expect is :

3

Here is a playground with my example.

1 Answers

To avoid "slurping" the input, you would use either reduce or foreach. Here's a suitable abstraction built from reduce:

def count(s; f; g):
  reduce s as $s ([0,0];
    if $s|f then .[0]+=1 else . end
    | if $s|g then .[1]+=1 else . end);

With this, you would invoke jq with the -n command-line option and run a query such as:

count(inputs|.value; .=="active"; .=="inactive")

Notice that one cannot use count/1 (defined analogously) twice since inputs consumes the input stream.

Related