ZSH:連想配列名と内容を動的に設定するには?

ZSH:連想配列名と内容を動的に設定するには?

次のように連想配列を設定しました。

$ foo=test
$ set -A $foo "a b" "1 2" "c d" "3 4"
$ for key val in "${(@kv)test}"; do echo "$key -> $val" done
a b -> 1 2
c d -> 3 4

"a b" "1 2" "c d" "3 4"配列の内容を変数に置き換える方法は?

ベストアンサー1

set -A array value1 value21980年代初頭に一般的な配列を定義するために使用された古いksh構文。連想配列を定義せず、ksh88 とのみ互換性があります。

kパラメータ拡張フラグは、v連想配列の変数にのみ意味があります。他の型の変数(通常の配列を含む)の場合、単に無視されます。したがって、ここでは、"${(@kv)test}"または通常の配列²のすべての要素に展開されます。"${(@)test}""$test[@]"

連想配列を宣言するには、最新の方法を使用することをお勧めします。

assoc=(
  'key 1' 'value 1'
  'key 2' 'value 2'
)

文法³assoc連想配列として宣言した後そして:

typeset -A assoc

最新バージョンではtypeset二重キーワード/組み込みであるため、次を使用して同時に宣言して割り当てることもできます。

typeset -A assoc=(
  'key 1' 'value 1'
  'key 2' 'value 2'
)

これにより、次のことができます。

printf '"%s" => "%s"\n' "${(@kv)assoc}"

または

for k v ("${(@kv)assoc}") print -r -- "$k => $v"

または:

for k ("${(@k)assoc}") print -r -- "$k => $assoc[$k]"

対応するキーと値を繰り返します。

キーと値リストの変数に格納されている名前で連想配列を定義するには、次のようにします。

setassoc() {
  typeset -gA $1; shift
  eval "$1"='( "$@[2,-1]" )'
}
foo=test
setassoc $foo 'key 1' 'value 1' 'key 2' 'value 2'

または、キーと値のリストが通常の配列変数に格納されている場合:

array=('key 1' 'value 1' 'key 2' 'value 2')
setassoc $foo "$array[@]"

しかし、set -Aここを使用することは避けられますがeval(ここではこのように使用するのは間違っていませんeval)、まず変数を連想配列に設定する必要があります。

foo=test
typeset -A $foo
set -A $foo "$array[@]"

kshエミュレーションが有効になっている場合(具体的にはksharraysそのオプションが有効になっている場合)、これを次のように変更する必要があります。

set -A $foo -- "$array[@]"

1 David Kornは、Bourneシェルがすでに使用されていた-Aため、このオプションを選択しました。また、ksh93またはzshから行を配列として読み取るために使用されるset -a理由も説明しました。アレイデザインはksh88に基づいており(アレイデザインはkshよりもcshに近いですが)、代わりに選択されましたがサポートされていません。混乱の原因の1つは、通常の配列宣言と関連配列宣言(両方ともkshで)です。read -Abashset -Azshread -aread -Atypeset -atypeset -A

² そして、for k v合計を配列の要素に順番に割り当てます。これにより、出力が説明され、割り当てと同じ順序である理由が説明されます(一方、連想配列では順序は保証されません)。kv

³構文は実際に~からzshは1990年に登場し、後にksh93(大きな変数型の一部として複合変数も含まれています)とbash(配列は1996年2.0まで出現しません)に登場しましたが、cshから多くのインスピレーションを受けました(p. A 1970年代後半の配列を使用したシェル)構文は次のとおりです。set array = (foo bar)

おすすめ記事