Shell quiz: emulate an associative array

Most shells flavors do not have associative arrays a.k.a. maps.

  • How would you emulate an associative array?

I had this problem once and found a working solution, but I don't want to spoil the game hence I wont tell it.
Wonder if anyone comes up with something better.

validname()
 case $1 in
   [!a-zA-Z_]* | *[!a-zA-Z0-9_]* ) return 1;;
 esac

setvar()
{
  validname "$1" || return 1
  eval "$1=\$2"
}

getvar()
{
  validname "$1" || return 1
  eval "printf '%s\n' \"\${$1}\""
}


## sample run
n=whatever
setvar board_$n Testing || { echo bad; exit 1; }
getvar board_$n

@cfajohnson

Good!

That solution leverages the shell own symbol table (forget my inaccuracy), therefore it is efficient.

The array name board is implemented as a prefix of the many variable names this technique generates.
Of course to avoid name clash you have to remember to not use that prefix in the name of other variables that your program may have.

If I can say anything, I would like to point out that a better approach would be to have setvar and getvar use an internal fixed prefix. The fixed prefix would be something like aa4732_, therefore the chances of it to be used in other parts of the program would be very small.

Perhaps the call syntax can be more clear and useful this way:

setvar arrayname key value
getvar arrayname key
setvar colors "yellow" "#FFFF00" # would internally do aa4732_colors_yellow="#FFFF00"
setvar colors "red" "#FF0000"
getvar colors "yellow"
getvar colors "red"

A serious issue is that keys can only be strings in the alphabet [A-Za-z0-9_].
Do anyone see an approach that doesn't have this issue and that is reasonably quick for a small key set?

while i see its quite interesting, but what's the point of these?

What's the point of... what?

The point of implementing an associative array is to have a useful data structure that is missing in just about any shell except ksh93.

... , zsh and bash4.