This is how I use jq to conditionally add an element to an array only if it doesn’t exist there already. In other words, add an element to an array only if it doesn’t create a duplicate in the array. This is particularly helpful when I’m scripting a JSON transformation and want to make it idempotent.
echo '{"values": ["a", "b"]}' | \
jq --arg newvalue 'c' \
'if .values | index($newvalue)
then .
else .values += [$newvalue]
end'
How It Works
Output Object Unchanged
echo '{"values": ["a", "b"]}' | jq '.'
Add Value to Array inside Object
echo '{"values": ["a", "b"]}' | jq --arg newvalue 'c' '.values += [$newvalue]'
Duplicate
If we add a value that is already in the array, we end up having it twice.
echo '{"values": ["a", "b"]}' | jq --arg newvalue 'a' '.values += [$newvalue]'
Check If Already Exists
Conditional Check If Value Already Appears
echo '{"values": ["a", "b"]}' | jq --arg newvalue 'c' '.values | index($newvalue)'
null
echo '{"values": ["a", "b"]}' | jq --arg newvalue 'a' '.values | index($newvalue)'
0
Note: in jq the only falsy values are false and null (0 is NOT a falsy value)
echo '{"values": ["a", "b"]}' | jq --arg newvalue 'c' 'if .values | index($newvalue) then "exists" else "does not exist" end'
“does not exist”
echo '{"values": ["a", "b"]}' | jq --arg newvalue 'a' 'if .values | index($newvalue) then "exists" else "does not exist" end'
“exists”
Conditionally Add Value to Array
echo '{"values": ["a", "b"]}' | jq --arg newvalue 'a' 'if .values | index($newvalue) then . else .values += [$newvalue] end'
(unchanged)
echo '{"values": ["a", "b"]}' | jq --arg newvalue 'c' 'if .values | index($newvalue) then . else .values += [$newvalue] end'
{
"values": [
"a",
"b",
"c"
]
}
With Indentation
echo '{"values": ["a", "b"]}' | \
jq --arg newvalue 'c' \
'if .values | index($newvalue)
then .
else .values += [$newvalue]
end'
As Mattias Wadman, one of the maintainers of
jqpoints out in this Mastodon post.If we don’t care about the order of the array elements, we can use the builtin unique function.
e.g.