ZSH Sorting Associative Arrays

Last Updated on February 10, 2022 EST by Jordan

As I dive into ZSH more and more and start to put more hours into zshbop, I’m finding it harder to locate good ZSH documentation. I got stuck with an associative array being unsorted, why? I started to document all of the scripts and commands I’ve created and used the following format.

help_files[gcp]='GIT commit then push!'

This makes it super easy to explain all of the scripts and functions I have without having to place them all in one help file. I just use the associative array just above the function I’m writing.

The problem is that they’re unordered as I create them as needed. This results in the help file spewing the following out.

------------------------
-- Help Command Categories --
------------------------

  help php                       - PHP related commands
  help wordpress                 - WordPress related commands
  help ssh                       - SSH related commands
  help nginx                     - Nginx related commands
  help software                  - Software related commands
  help software_description      - -- To install, run software <cmd>
  help ubuntu                    - Ubuntu OS related commands
  help mail                      - All mail related commands
  help git                       - Git related commands
  help mysql                     - MySQL related commands
  help linux                     - Linux related commands
  help core                      - Core commands

It’s super ugly. So I started to look at trying to sort the associate array somehow. I first thought I could actually sort the array data, take out the data and then put it back in. But I thought that was too much work, and I wouldn’t understand the code as it was a copy and paste snippet I found on Stack Overflow.

I started to use ZSH substitution modifiers, which I had already been using for creating my command categories and other help verbiage. Here’s an example of listing all of the category commands.

help_files[nginx]='Nginx related commands'
help_files[php]='PHP related commands'
help_files[mail]='All mail related commands'
help_files[ubuntu]='Ubuntu OS related commands'

for key value in ${(kv)help_files}; do
        printf '%s\n' "  help ${(r:25:)key} - $value"
done

This works out well and the output is what you see in the previous code snippet. It’s just not sorted.

So I tried to work with ZSH substitutions but I couldn’t figure out how to return a key and values while also sorting. I couldn’t use (okv) this broke and I don’t know why. Still learning….

So instead I just grabbed the key, and sorted it. Then passed the kay to the array to print out the value. So easy.

        for key in ${(kon)help_zshbop}; do
                printf '%s\n' "  zshbop ${(r:25:)key} - help_zshbop[$key]"
        done

Did you like this article?