密钥$ {!a [@]}和值$ {a [@]}的关联数组是否以相同的顺序展开?

问题描述 投票:4回答:1

在bash中,关联数组(也称为字典或散列映射)是无序的。对于关联数组a,我们可以使用${!a[@]}列出所有键(也称为索引),使用${a[@]}列出所有值。我知道这些结构不会按固定顺序扩展。我想知道是否至少有一些保证。我找不到任何东西。然而,[ "${a[*]}" = ${a[*]} ]在任何实施中都会失败似乎是不现实的。同样,似乎${!a[@]}的扩展顺序与${a[@]}相同。如果我们在x的位置n找到关键的${!a[@]},那么我们也会在${a[x]}的位置n找到值${a[@]}。当然,我们假设在a${!a[@]}的扩展之间没有修改${a[@]}

Example:

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    ...

Question

  • 对于任何现有的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"

Bonus Questions

  • 在bash的手册或其他一些官方文件中,${!a[*]}${a[@]}的扩张订单是否有任何保证?
  • 我们可以假设实施本身的进一步/其他保证吗?其中一些保证会因不同版本的bash而改变吗?这些保证中的一些可能会在即将推出的bash版本中发生变化吗?
bash associative-array
1个回答
1
投票

我没有在bash手册页中看到任何关联数组的键排序(我使用的是4.3.48)。看到bash 5.0的源代码(hashlib.c)也表明bash使用最简单的散列基于XOR的算法而没有任何随机化,所以顺序不应该在进程或机器之间随机化,不像你找到的其他更复杂的算法,说,Perl。

话虽如此,依靠特定的关键顺序或顺序不变仍然是不明智的,因为Perl-land的经验教会了我们。此外,由于bash手册页没有说明订购,因此无法保证。哈希实现可以随时替换或重写。

© www.soinside.com 2019 - 2024. All rights reserved.