I am migrating from ksh
to fish
. I am finding that I miss the ability to define an associative array, hash table, dictionary, or whatever you wish to call it. Some cases can be simulated as in
set dictionary$key $value
eval echo '$'dictionary$key
But this approach is heavily limited; for example, $key
may contain only letters, numbers, and underscores.
I understand that the fish
approach is to find an external command when one is available, but I am a little reluctant to store key-value information in the filesystem, even in /run/user/<uid>
, because that limits me to "universal" scope.
How do fish
programmers work around the lack of a key-value store? Is there some simple approach that I am just missing?
Here's an example of the sort of problem I would like to solve: I would like to modify the fish_prompt
function so that certain directories print not using prompt_pwd
but using special abbreviations. I could certainly do this with a switch
command, but I would much rather have a universal dictionary so I can just look up a directory and see if it has an abbreviation. Then I could change the abbreviations using set
instead of having to edit a function.
You can store the keys in one variable and values in the other, and then use something like
if set -l index (contains -i -- foo $keys) # `set` won't modify $status, so this succeeds if `contains` succeeds
echo $values[$index]
end
to retrieve the corresponding value.
Other possibilities include alternating between key and value in one variable, though iterating through this is a pain, especially when you try to do it only with builtins. Or you could use a separator character and store a key-value pair as one element, though this won't work for directories because variables cannot contain \0 (which is the only possible separator for paths).