How to check for an optional field in jq?

Viewed 1504

I have this jq filter:

some_command | jq -r '.elements[] | select(.state=="LIVE" and .group == "some_text" and .someFlag == false) | .name'

someFlag is an optional field. Hence, when it is absent, the expression doesn't show any result. I want to check for:

  • if someFlag is present, pass the check only if it has the false value
  • if someFlag is not present, treat it as false

How can I do that?

2 Answers

I used the alternative operator, //:

(.someFlag // false) == false)

So, if .someFlag isn't there, it is treated as false.

The whole expression is:

some_command | jq -r '.elements[] | select(.state=="LIVE" and .group == "some_text" and (.someFlag // false) == false)) | .name'

From jq documentation:

Alternative operator //:

A filter of the form a // b produces the same results as a, if a produces results other than false and null. Otherwise, a // b produces the same results as b.

This is useful for providing defaults: .foo // 1 will evaluate to 1 if there’s no .foo element in the input. It’s similar to how or is sometimes used in Python (jq’s or operator is reserved for strictly Boolean operations).

In the given context, the direct translation of:

  • if someFlag is present, pass the check only if it has the false value
  • if someFlag is not present, treat it as false

to jq is:

if has("someflag") then .someflag == false else false end

Adjusted filter

.elements[]
| select(.state == "LIVE"
         and .group == "some_text"
         and (if has("someFlag")
              then .someFlag == false 
              else false
              end))
| .name

[This response has been updated in accordance with the update to the Q.]

Related