title: Do keys ${!a[@]} and values ${a[@]} of associative arrays expand in the same order?
body: <p>In bash, associative arrays (also known as dictionaries or hash maps) are unordered. For the associative array <code>a</code> we can list all keys (also known as indices) with <code>${!a[@]}</code> and all values with <code>${a[@]}</code>. I know that these constructs do not expand in a fixed order. I wondered if there are at least <em>some</em> guarantees. I couldn't find any. However, it seems unrealistic that <code>[ &quot;${a[*]}&quot; = ${a[*]} ]</code> will fail in any implementation. Likewise, it seems that <code>${!a[@]}</code> expands in the same order as <code>${a[@]}</code>. If we find key <code>x</code> at position <em>n</em> in <code>${!a[@]}</code> then we will find value <code>${a[x]}</code> at position <em>n</em> in <code>${a[@]}</code> too. Of course we assume that <code>a</code> is not modified between the expansions of <code>${!a[@]}</code> and <code>${a[@]}</code>.</p>
  <h3>Example:</h3>
  <pre><code>declare -A a=([x]=1 [y]=2 [z]=3)
  printf %s\\n &quot;${!a[*]}&quot; &quot;${a[*]}&quot;
  
  # 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    ...
  </code></pre>
  <h3>Question</h3>
  <ul>
  <li>For any existing bash version and associative array <code>a</code>, could <code>${!a[@]}</code> and <code>${a[@]}</code> expand in such a way that keys and and their corresponding values have a different order? In other words:</li>
  </ul>
  <p>
  <pre><code># Are there values for a and i
  # such that this script could print &quot;different order&quot;
  declare -A a=(...)
  declare -i i=...
  keys=(&quot;${!a[@]}&quot;)
  values=(&quot;${a[@]}&quot;)
  [ &quot;${a[keys[i]]}&quot; != &quot;${values[i]}&quot; ] &amp;&amp; echo &quot;different order&quot;
  </code></pre>
  <h3>Bonus Questions</h3>
  <ul>
  <li><sub>Are there any <strong>guarantees</strong> on the expansion orders of <code>${!a[*]}</code> and <code>${a[@]}</code> <strong>in bash's manual</strong> or some other official document?
  </sub></li>
  <li><sub>Can we assume further/other <strong>guarantees from the implementation</strong> itself? Did some of these guarantees change with different versions of bash? Are some of these guarantees likely to change in upcoming versions of bash?</sub></li>
  </ul>