【问题标题】:Do keys ${!a[@]} and values ${a[@]} of associative arrays expand in the same order?关联数组的键 ${!a[@]} 和值 ${a[@]} 是否以相同的顺序展开?
【发布时间】:2019-06-15 19:08:06
【问题描述】:

在 bash 中,关联数组(也称为字典或哈希映射)是无序的。对于关联数组a,我们可以用${!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"

额外问题

  • ${!a[*]}${a[@]}的扩展命令在bash的手册或者其他官方文档中是否有保证
  • 我们能否进一步/其他实施保证本身?这些保证中的一些是否会随着 bash 的不同版本而改变?在即将发布的 bash 版本中,其中一些保证是否可能会发生变化?

【问题讨论】:

    标签: bash associative-array


    【解决方案1】:

    我在 bash 手册页中没有看到任何提及关联数组的键顺序(我使用的是 4.3.48)。查看 bash 5.0 (hashlib.c) 的源代码还表明 bash 使用了最简单的基于散列 XOR 的算法,没有任何随机化,因此与您发现的其他一些更复杂的算法不同,顺序不应在进程或机器之间随机化例如,在 Perl 中。

    话虽如此,依赖特定的键顺序或恒定的顺序仍然是不明智的,正如 Perl 领域的经验告诉我们的那样。此外,由于 bash 手册页没有说明订购,因此无法保证。哈希实现可以随时替换或重写。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-10
      • 2013-08-24
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多