web-dev-qa-db-ja.com

zshは、間接展開を介して連想配列内のキーの存在をテストします

したがって、次のような操作を行うことで、間接展開を介して通常のパラメーターの存在をテストできることを知っています。

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

そして、次のようなことを行うことで、連想配列内のキーの存在をテストできることを私は知っています。

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

ただし、この2つを組み合わせて、間接展開を介して連想配列内にキーが存在するかどうかをテストする方法がわかりません。これはevalを使用せずに可能ですか?

以下を含むいくつかの組み合わせを試しましたが、どれも機能しませんでした。

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"
3
Matt Wilder

ここで説明 。値の受け渡しを回避するには、別のパラメーター展開(_${:-Word}_)で正しい形式の文字列を使用する必要があります。これは、${(P)+...}によって展開されます。

_(( ${(P)+${:-${bar}[abc]}} )) && print OK || print FAIL
_
1
don_crissti

${+param}を使用する方法はわかりませんが、代わりに[[ -v $param ]]を使用できます。

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
0
GammaFunction