私は「Bash Pocket Reference」の本を読んで、連想配列に関するセクションを読んだ。ここで本のサンプルコードを試してみると、予期しない答えが得られました。
istanev@inspiron5559:~$ data=([joe]=30 [mary]=25)
istanev@inspiron5559:~$ echo ${data[joe]}
25
istanev@inspiron5559:~$ echo ${data[mary]}
25
data[joe]は30を返すべきではありませんか?なぜ25を返すのですか?私のbashバージョンは4.3.46(1)リリースです。
ベストアンサー1
デフォルトでは、bashは配列をインデックス配列として扱います。
この場合、インデックスは算術式として評価されます。
$ joe=3 mary=6
$ unset data
$ data=([joe]=111 [mary]=bbb)
$ declare -p data
declare -a data=([3]="111" [6]="bbb")
出力には、次のようないくつかの点が表示されます。
- 配列は
-a
出力からインデックス付けされます。 - 配列には2つの値が含まれています。
joe
値のインデックスは変数sumの数値と一致しますmary
。- 配列に含まれる値は文字列です。
これは、インデックスが引用されている場合でも同様です(単一引用符でも)。
$ joe=3 mary=6
$ unset data
$ data=(["joe"]=111 ["mary"]=bbb)
$ declare -p data
declare -a data=([3]="111" [6]="bbb")
インデックスとして使用される文字列が数値を含むように定義されていない場合は、とにかく値が0の算術式として評価されます。
$ unset joe ; unset mary ; unset data
$ data=([joe]=111 [mary]=bbb)
$ declare -p data
declare -a data=([0]="bbb")
[joe]=111
評価結果はで、[0]=111
インデックスの配列0
はに設定されます111
。ただし、と[mary]=bbb
評価され、[0]=bbb
indexの配列値がに置き換え0
られますbbb
。
実際に連想配列を持つには、使用する前に定義する必要があります。
データが含まれている間は変更できません。配列の設定は次のとおりです。
$ declare -A data
bash: declare: data: cannot convert indexed to associative array
ただし、これを消去するには、次のようにします。
$ joe=3 ; mary=6 ; unset data
$ declare -A data
$ data=([joe]=111 [mary]=bbb)
$ declare -p data
declare -A data=([joe]="111" [mary]="bbb" )
ご覧のとおり、インデックスとして使用される文字列も有効な変数名であり、値が含まれているかどうかは重要ではありません。連想配列の文字列インデックスとして使用されます。