在bash中,关联数组(也称为字典或散列映射)是无序的.对于关联数组,我们可以使用${!a [@]}列出所有键(也称为索引),并使用${a [@]}列出所有值.我知道这些结构不会按固定顺序扩展.我想知道是否至少有一些保证.我找不到任何东西.但是,[“${a [*]}”= ${a [*]}]在任何实现中都会失败,这似乎是不现实的.同样,似乎${!a [@]}的扩展顺序与${a [@]}相同.如果我们在${!a [@]}的位置n找到关键x,那么我们也会在${a [@]}的位置n找到值${a [x]}.当然,我们假设在${!a [@]}和${a [@]}的扩展之间没有修改a.
例:
declare -A a=([x]=1 [y]=2 [z]=3)
printf %s\\n "${!a[*]}" "${a[*]}"
# As output I would expect one of the following blocks ...
# (corresponding keys and values are in the same column)
x y z x z y y x z y z x z x y z y x
1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
# ... but never something like ...
# (at least one key doesn't share a column with its value)
x y z x y z y x z
1 3 2 2 3 1 2 3 1 ...
题
>对于任何现有的bash版本和关联数组a,${!a [@]}和${a [@]}是否可以扩展密钥及其对应的值具有不同的顺序?换一种说法:
# Are there values for a and i
# such that this script could print "different order"
declare -A a=(...)
declare -i i=...
keys=("${!a[@]}")
values=("${a[@]}")
[ "${a[keys[i]]}" != "${values[i]}" ] && echo "different order"
奖金问题
>在bash的手册或其他一些官方文件中,是否对${!a [*]}和${a [@]}的扩展订单有任何保证?
>我们可以从实施本身做出进一步/其他保证吗?其中一些保证会因不同版本的bash而改变吗?这些保证中的一些可能会在即将推出的bash版本中发生变化吗?
最佳答案 我没有在bash手册页中看到任何关联数组的键排序(我使用的是4.3.48).看到bash 5.0(hashlib.c)的源代码也表明bash使用最简单的散列基于XOR的算法而没有任何随机化,所以顺序不应该在进程或机器之间随机化,这与你发现的其他一些更复杂的算法不同比方说,Perl.
话虽如此,依靠特定的关键顺序或顺序不变仍然是不明智的,因为Perl-land的经验教会了我们.此外,由于bash手册页没有说明订购,因此无法保证.哈希实现可以随时替换或重写.