Associative arrays in Zsh are actually just hash tables disguised as regular arrays, letting you store values with arbitrary string keys.
Here’s a quick look at them in action:
# Declare an associative array
typeset -A my_map
# Add some key-value pairs
my_map[apple]="red"
my_map[banana]="yellow"
my_map[grape]="purple"
# Access values by key
echo $my_map[apple] # Output: red
echo $my_map[banana] # Output: yellow
# Iterate over keys
for fruit in "${!my_map[@]}"; do
echo "Key: $fruit, Value: ${my_map[$fruit]}"
done
# Output:
# Key: apple, Value: red
# Key: banana, Value: yellow
# Key: grape, Value: purple
# Check if a key exists
if [[ -v my_map[orange] ]]; then
echo "Orange exists"
else
echo "Orange does not exist" # Output: Orange does not exist
fi
# Delete a key-value pair
unset my_map[grape]
echo "Grape deleted."
# Get the number of elements
echo "Number of elements: ${#my_map[@]}" # Output: Number of elements: 2
Associative arrays shine when you need to associate data with descriptive labels rather than just sequential indices. Think about mapping usernames to user IDs, error codes to their descriptions, or configuration settings to their values. Instead of juggling multiple regular arrays and trying to keep their indices in sync, you can store all related information in a single associative array, making your scripts more readable and less error-prone.
Internally, Zsh implements associative arrays using hash tables. When you assign a value to my_map[key], Zsh calculates a hash of the key string. This hash determines where in an internal data structure the value is stored. This hashing mechanism allows for very fast lookups, insertions, and deletions, typically in average O(1) time, regardless of how many elements are in the array. The typeset -A command is what tells Zsh to treat the variable my_map as an associative array, allocating the necessary hash table structure for it. The special syntax ${!my_map[@]} expands to a list of all the keys currently stored in the array, and ${my_map[key]} retrieves the value associated with that specific key.
The -v test for checking key existence is a Zsh-specific feature. It’s more efficient than trying to access a non-existent key and checking if the result is empty, as it directly queries the internal hash table for the key’s presence.
What most people don’t realize is that the keys in Zsh associative arrays are treated as literal strings. This means that if you have keys like "1" and 1, they are distinct. Zsh doesn’t automatically coerce numeric strings to integers when used as keys in associative arrays, unlike how it might in some other contexts with regular arrays or arithmetic expansions. This distinction is crucial if you’re migrating logic from other languages or shell environments where implicit type coercion might occur.
The next hurdle you’ll likely encounter is handling more complex data structures within associative arrays, such as nesting them or storing arrays as values.