If I wanted to pass the keys and values of an associative array in bash separately, and used something like
./foo.py -k "${!args[@]}" -v "${args[@]}"
would they come out in the same order? I don't really care what other the k=v pairs are stored in, but I do need to know if I could count on the keys and values coming out such that the 3rd item in the key array is in fact the key for the 3rd item in the value array.
I know that associative arrays are "unordered" and that whatever order you add them to the array is irrelevant to how they're output, but I'm wondering if the underlying storage behavior means they will always output in the same order.
It appears that the answer is yes, the keys and values will always be in the same order, based on the code I found in Bash version 4.3, assoc.c
, available here. The keys and values of the array are retrieved by the functions assoc_keys_to_word_list
and assoc_to_word_list
, respectively. Both of these functions delegate to assoc_to_word_list_internal
, which runs the same loop in both cases, and only differentiates the type of item being retreived based on the t
parameter (lines 482-503):
static WORD_LIST * assoc_to_word_list_internal (h, t) HASH_TABLE *h; int t; { WORD_LIST *list; int i; BUCKET_CONTENTS *tlist; char *w; if (h == 0 || assoc_empty (h)) return((WORD_LIST *)NULL); list = (WORD_LIST *)NULL; for (i = 0; i < h->nbuckets; i++) for (tlist = hash_items (i, h); tlist; tlist = tlist->next) { w = (t == 0) ? (char *)tlist->data : (char *)tlist->key; list = make_word_list (make_bare_word(w), list); } return (REVERSE_LIST(list, WORD_LIST *)); }
In case you are wondering, make_word_list
is defined in array.c/h
. It just appends a new WORD_LIST
node to the existing linked list.
While this provides no contractual guarantee that the behavior you expect will always be supported, it is a pretty good indication that you can use your calling convention safely, at least for now. The fact that associative arrays are Bash-only makes the implementation more of a valid reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With