Author: | Adrian Perez <aperez@igalia.com> |
---|---|
Copyright: | 2008-2009 Igalia S.L. |
License: | GPL3 |
Abstract
Efficient dictionary-like structures i.e. a hash table.
Contents
A hash table is a data structure which stores a set of (key, value) pairs in a way that enables for fast lookup of values when the keys are known. Those hash tables are used mainly with string keys and values, so they are sometimes called dictionaries as well.
A hash table can be accessed by using its unique identifier. New identifiers can be obtained using hash_new, and albeit they are regular strings and can be printed usually you do not need to know about them:
(bill) use data/hash
(bill) h=$(hash_new)
(bill) echo $h
:bill:0709bd8abbe7139f40dd48004e85a5ea00dd4bd3:
Now you can use the hash table, the basic functions for this are hash_set and hash_get:
(bill) hash_set $h firstname 'John'
(bill) hash_set $h lastname 'Doe'
(bill) hash_set $h email 'john@doe.org'
(bill) printf '%s %s <%s>\n' \
...) "$(hash_get $h firstname)" \
...) "$(hash_get $h lastname)" \
...) "$(hash_get $h email)"
John Doe <john@doe.org>
We can check whether a key is present in a hash table using hash_has, which is nice to do checking. Note that hash_get will return an empty string and have a non-zero exit status:
(bill) hash_has $h email && echo Yes || echo No
Yes
(bill) hash_has $h age && echo Yes || echo No
No
(bill) v=$(hash_get $h age)
(bill) echo "code $?, value '$v'"
code 1, value ''
Finally, you can obtain a array of keys present in the hash table using hash_keys_escaped. Once you are done using a table, do not forget to use hash_clear on it:
(bill) keys=( $(hash_keys_escaped $h) )
(bill) echo "Keys: ${keys[*]}"
Keys: lastname firstname email
(bill) hash_clear $h
(bill) echo "Keys: ${keys[*]}"
Keys:
Keys can be any string which can be represented in bash source code. You can even use “funny” keys containing escape and control characters as long as you do not try to iterate over keys containing them.
Warning
Use only printable characters for hash table keys when it is needed to iterate over the keys of a hash table using hash_keys_iter, hash_keys or hash_keys_escaped.
As hash table identifiers are strings, you can use them as values of another hash table, thus creating nested tables:
(bill) outer=$(hash_new)
(bill) inner=$(hash_new)
(bill) hash_set $outer subtable $inner
(bill) hash_set $inner value 'I am inside inner'
(bill) hash_get $(hash_get $outer subtable) value
I am inside inner
This way complex data structures can be created. The syntax used to create them is not very pretty, but at least it is possible.
hash_new
Creates a new hash table. Returns a has table identifier which is needed as first argument to all the other functions of the module.
hash_set hash_id key value
Associates a key with a value. The hash_id parameter must be an identifier obtained with hash_new.
hash_get hash_id key
Gets the value associated with a key. The hash_id parameter must be an identifier obtained with hash_new. The exit status is non-zero when an element is not found.
hash_del hash_id key
Deletes a (key, value) pair from a hash table. The hash_id parameter must be an identifier obtained with hash_new.
See also: hash_set, hash_has, hash_clear.
hash_has hash_id key
Checks whether a given key is set in a hash table. The hash_id parameter must be an identifier obtained with hash_new. The exit status is zero when the keys exists, and non-zero otherwise.
See also: hash_set.
hash_keys_iter hash_id callback
Iterates over all keys of the given hash table hash_id. The callback will be called with the hash_id as first argument
Warning
Do not add or remove keys while iterating over the elements, behaviour is undefined.
See also: hash_keys_escaped, hash_keys.
hash_keys hash_id
Gathers all keys of a given hash table and print one key per line. It may be better to use hash_keys_escaped if you want to save the key list into an array.
See also: hash_keys_escaped, hash_keys_iter.
hash_keys_escaped hash_id
Gathers all keys of a given hash table and print one key per line. Unlike hash_keys, elements are escaped so you can reuse the output for gathering the key names into an array:
h=$(hash_new)
for i in $(seq 10) ; do
hash_set $h "key $i" "value $i"
done
h_heys=( $(hash_keys_escaped $h) )
See also: hash_keys, hash_keys_iter.
hash_clear hash_id
Empties a hash table. The hash_id parameter must be a valid identifier obtained with hash_new.