31

In zsh, I want to iterate over an associative array. I need both keys and values. But when I iterate over the associative array normally (for x in $assoc_array), I get only values.

All examples I've looked at show that, given a key, you can get its value from an associative array. My problem is getting the set of keys to begin with.

Does zsh support iterating over keys in an associative array?

1
  • If you have just a small list this might be an option: for i in a,b c_s,d ; do KEY=${i%,*}; VAL=${i#*,}; echo $KEY" XX "$VAL; done
    – math
    May 16 '14 at 14:44
29

You can get both keys and values at once with this nifty parameter expansion:

for key val in "${(@kv)assoc_array}"; do
    echo "$key -> $val"
done

See Parameter Expansion Flags in the Zsh manual.

6
  • This is way simpler +1
    – TimSum
    Sep 12 '17 at 5:53
  • This doesn't work when the keys or values have spaces in them
    – Max Coplan
    Sep 9 '19 at 1:33
  • (@kv) is better (it works with quotes, too.).
    – HappyFace
    Oct 10 '20 at 16:23
  • @HappyFace edited Oct 24 '20 at 1:38
  • 1
    @Gairfowl edited Jan 23 at 17:14
37

I continued searching after asking my question and found this answer on the Unix StackExchange:

typeset -A assoc_array
assoc_array=(k1 v1 k2 v2 k3 v3)

for k in "${(@k)assoc_array}"; do
  echo "$k -> $assoc_array[$k]"
done

Output is:

k1 -> v1
k2 -> v2
k3 -> v3
3
  • 2
    For anyone wanting to test this in a useful way, try with the builtin $options. (See man zshoptions)
    – mVChr
    Oct 29 '16 at 9:29
  • What if the key is not an increasing number like foo, bar, etc like arr[foo]=baz?
    – Timo
    Dec 17 '17 at 20:28
  • 2
    @Timo I don’t think you should expect any specific order in associative arrays. Nov 7 '20 at 23:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.