我正在尝试使用bash中的数组来管理关联数组列表,而我似乎无法找到哪些不正确.
我正在做的事情:
array=(a b c d)
for i in ${array[@]}; do
declare -A $i
done
a[key]=avalue
b[key]=bvalue
c[key]=cvalue
d[key]=dvalue
Run Code Online (Sandbox Code Playgroud)
这一切似乎工作正常,因为我可以手动返回值通过引用${a[key]}就好了.
但是,当我试图迭代使用array变量时,它并没有真正给我我期望的东西.
for index in ${array[@]}; do
echo ${index[key]}
done
Run Code Online (Sandbox Code Playgroud)
回来就像我要跑的一样
for index in ${array[@]}; do
echo $index
done
Run Code Online (Sandbox Code Playgroud)
我觉得我错过了一些简单的东西,但寻找答案并没有找到任何解决方案.任何援助将不胜感激.
这是一个解决方案,使用shell间接.这适用于bash支持关联数组的任何数组.间接必须包含整个引用,包括下标,这有点尴尬.
for index in "${array[@]}"; do
indexkey=${index}[key]
echo "${!indexkey}"
done
Run Code Online (Sandbox Code Playgroud)
使用现代bash(至少v4.3),您可以使用nameref声明,它创建别名.这样更方便,因为您可以使用具有相同别名的不同键:
for index in "${array[@]}"; do
declare -n subarray=$index
echo "${subarray[key]}"
done
Run Code Online (Sandbox Code Playgroud)
正如Etan Reisner在评论中指出的那样,这个问题在Bash FAQ条目中有一定篇幅.但是,在我编写的那一天,该FAQ条目包含免责声明"检修此页面需要一些时间和工作",而且FAQ条目目前还不像人们所希望的那样清晰.所以这是我的简短摘要:
declare(和其他相关的内置命令,其中包括export,local,和typeset)评估他们的论点.因此,您可以在declare语句中构建变量名称.
由于declare也可以用于赋值(只要使用相同的声明),就可以在declare语句中建立索引变量名.
如果您使用的是bash4.3或更高版本,则可以使用namerefs(typeset -n或declare -n)来模拟数组值.这真的是你可以从bash函数返回一个数组的唯一方法,但它仍然有点尴尬,因为它要求函数的调用者提供一个带有数组名称的参数; 此外,它不是完全健壮的,因为名称将在函数的范围内使用,因此它可能被局部变量遮蔽.需要注意.
使用变量间接可能没有其他充分的理由.如果您发现自己需要它,请考虑是否可以采用不同的方式构建程序.您可以使用字符串连接折叠关联键.例如:
my_array[${place}:${feature}]
Run Code Online (Sandbox Code Playgroud)
只要没有${place}包含冒号的值(当然,您可以使用不同的字符而不是冒号),它将工作.
小心钥匙.如果数组被声明为关联的,则通常或多或少地评估键,但如果它是普通的索引数组,则将键计算为算术表达式.结果是
declare -A assoc
declare -a indexed
key=42
# This assigns the element whose key is "key"
assoc[key]=foo
# This assigns the element whose key is 42
indexed[key]=foo
# If $key had not been defined, the above would have assigned
# the element whose key was 0, without an error message
Run Code Online (Sandbox Code Playgroud)