···11+---
22+title: Today I learned that bash has hashmaps
33+date: 2024-01-15
44+tags:
55+ - bash
66+ - til
77+ - crimes
88+---
99+1010+Hashmaps (associative arrays) are a great way to store a bag of key-value data. At work I was writing something that needed me to spawn a bunch of GPU instances, GPU availability is spread out by region and GPU type. I wanted to store a mapping of GPU kind to region name and for some reason I thought it would be a good idea to do it in bash. I was horrified to find out that bash has hashmaps, and decided to write this note to tell you how to use them.
1111+1212+Here's how you do it:
1313+1414+First, declare the hashmap with the `declare` builtin:
1515+1616+```shell
1717+# -A means associative array (hashmap)
1818+declare -A FLY_REGIONS
1919+```
2020+2121+Then add some values into it [from the fly.io documentation](https://fly.io/docs/gpus/gpu-quickstart/):
2222+2323+```shell
2424+FLY_REGIONS["a100-40gb"]="ord"
2525+FLY_REGIONS["a100-80gb"]="mia"
2626+FLY_REGIONS["l40s"]="ord"
2727+```
2828+2929+You can also predeclare the array with values in a read-only state:
3030+3131+```sh
3232+# -A means associative array (hashmap)
3333+# -r means read-only
3434+declare -A -r FLY_REGIONS=(
3535+ ["a100-40gb"]="ord"
3636+ ["a100-80gb"]="mia"
3737+ ["l40s"]="ord"
3838+)
3939+```
4040+4141+You can look up values with the same syntax you used to set them:
4242+4343+```shell
4444+echo "${FLY_REGIONS["a100-40gb"]}" # ord
4545+```
4646+4747+You can iterate over the keys with a `for` loop on the `@` value:
4848+4949+```shell
5050+for size in "${!FLY_REGIONS[@]}"; do
5151+ echo "size: $size, region: ${FLY_REGIONS[$size]}"
5252+done
5353+```
5454+5555+You can iterate over the values with a `for` loop on the `*` value:
5656+5757+```shell
5858+for region in "${FLY_REGIONS[@]}"; do
5959+ echo "region: $region"
6060+done
6161+```
6262+6363+You can delete individual keys with `unset`:
6464+6565+```shell
6666+unset FLY_REGIONS["a100-40gb"]
6767+```
6868+6969+If you need to delete the entire hashmap, you can also do it with `unset`:
7070+7171+```shell
7272+unset FLY_REGIONS
7373+```
7474+7575+Please don't use this for evil.