【问题标题】:Extracting indices from indexed array: guaranteed to be ordered?从索引数组中提取索引:保证是有序的?
【发布时间】:2019-09-04 03:50:32
【问题描述】:

我知道对于 关联 数组,数组键没有固有的顺序:

declare -A map=([a]=b [c]=d [e]=f)
echo "${!map[@]}"   # => e c a (perhaps)

但是索引数组呢?

试试这个:

declare -a list
for i in {1..1000}; do list[RANDOM]=1; done
echo "${!list[@]}"

索引似乎是按数字顺序排列的。但我可以依赖它吗?

【问题讨论】:

  • 您能否澄清您是否希望能够在特定 bash 版本(即可以通过检查 bash 的源代码来证明)或任意未来版本(即应该是设计/可以是通过文档证明)?
  • 当您将循环更改为for i in {1..10}; do echo "${!list[@]}"; list[RANDOM]=1; done 时,您会得出肯定的结论——似乎需要对它进行数字排序。是否可靠...?
  • @aaron,不管怎样
  • 我的直觉是,对于数字索引数组,答案是肯定的,但是维护者 Chet Ramey 应该可以通过 help-bash@gnu.org 获得权威的答案。

标签: bash


【解决方案1】:

确定性证明(如前所述)将是查阅来源(这仍然可能会因版本而异),因为查看了documentation,它没有提及${!name[@]} 的扩展顺序/ ${!name[*]}${name[@]} / ${name[*]}。然而,特别是。具有name=(value1 value2 … ) 分配的基本算术的位以及负索引的处理以及它的工作原理:

$ a=(1 2); a[8]=9; a[5]=6
$ indices=("${!a[@]}"); for i in "${indices[@]}"; do neg_i="$((-1 -${indices[-1]} + i))"; echo -e "a[$i]: ${a[$i]}\t\ta[$neg_i]: ${a[$neg_i]}" ; done
a[0]: 1         a[-9]: 1
a[1]: 2         a[-8]: 2
a[5]: 6         a[-4]: 6
a[8]: 9         a[-1]: 9

表明索引数组的索引必须考虑到它们的数值,以便从任一方向进行索引。这仍然可以在不需要数字排序(更不用说显示/扩展)的情况下实现。

稳定的排序也与其他语言一致.换句话说,我认为偏离这种行为不太可能是一个合理的决定。

两者都是间接推理,但不是明确的证据。

【讨论】:

    【解决方案2】:

    我花了一些时间阅读bash source。索引数组被实现为双向链表。

    插入新的数组元素 (ary[i]=value) 将遍历列表并插入元素以使索引保持数字排序:https://git.savannah.gnu.org/cgit/bash.git/tree/array.c#n548

    提取索引 (${!ary[@]}) 将列表从头部(具有最大索引的元素)返回到尾部(最小索引)并构建索引列表:https://git.savannah.gnu.org/cgit/bash.git/tree/array.c#n778

    所以,按照目前的实施方式,我认为我可以确信索引列表确实是有序的。

    【讨论】:

      猜你喜欢
      • 2020-06-19
      • 2022-01-23
      • 2023-03-31
      • 2015-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-06
      • 1970-01-01
      相关资源
      最近更新 更多