Conditionally add element to json array using jq

I am adding strings to a JSON array using jq and it works fine, but I would only like to add strings that don't exist yet. I experimented with unique, has, no, etc. I am missing a piece or two of puzzles.

Here is my initial json file, foo.json:

{ "widgets": [ { "name": "foo", "properties": [ "baz" ] }, { "name": "bar" } ] } 

Here the jq command I built adds a line, even if it already exists:

 $ cat foo.json | jq '.widgets[] | select(.name=="foo").properties |= .+ ["cat"]' 

Here is the last iteration of my attempt.

 $ cat foo.json | jq '.widgets[] | select(.name=="foo").properties | has("cat") | not | .properties += ["cat"]' jq: error: Cannot check whether array has a string key 
+4
source share
2 answers

There are many ways to do this.

Assuming the elements of the array must be unique, which implies your use case, you can simply pass the resulting array after adding through the unique filter.

 $ cat foo.json | jq '.widgets[] | select(.name=="foo").properties |= (.+ ["cat"] | unique)' 
+8
source

There is more than one way to throw a cat, as they say, but maybe this will give you some ideas:

 .widgets[] | select(.name=="foo") | select(.properties | index("cat") | not) | .properties += ["cat"] 

With your input, the result:

 { "name": "foo", "properties": [ "baz", "cat" ] } 

The following may be closer to what you are looking for:

 .widgets |= [ .[] | if .properties|index("cat")|not then .properties += ["cat"] else . end] 
0
source

All Articles