3

So I know that you can test for the existence of a regular parameter via indirect expansion by doing something like:

foo=1
bar=foo
(( ${(P)+bar} )) && print "$bar exists"

And I know you can test for the existence of a key inside an associative array by doing something like:

foo=([abc]=1)
(( ${+foo[abc]} )) && print "abc exists"

However I can't figure out how to combine the two and test for the existence of a key inside an associative array via indirect expansion. Is this possible without using eval?

I tried several combinations including the following, and none of them worked:

foo=([abc]=1)
bar=foo
(( ${(P)+bar[abc]} )) && print "$bar has key abc" # Test fails
(( ${(P)+${bar}[abc]} )) && print "$bar has key abc" # Passes for nonexistant keys
(( ${${(P)+bar}[abc]} )) && print "$bar has key abc" # Test fails
(( ${${(P)bar}+[abc]} )) && print "$bar has key abc" # prints "zsh: bad output format specification"
1

It's been discussed here. To avoid passing values you'll have to use a string with the right format in another parameter expansion (${:-word} that is) which is then expanded by ${(P)+...}:

(( ${(P)+${:-${bar}[abc]}} )) && print OK || print FAIL
| improve this answer | |
0

I don't know a way using ${+param}, but you can use [[ -v $param ]] instead:

foo=([abc]=1)
bar=foo

[[ -v "$bar""[abc]" ]] && print "$bar has key abc"
# or "$bar"[abc] or $bar''[abc] or $bar'[abc]'
# or any other way to suppress $bar[abc] being interpreted as a value in $bar
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.