Wednesday, May 15, 2013

associative arrays for ksh and earlier bash versions


Encodes the key (restricted to [a-z]) as a bit string of Huffman codes. Of limited usefulness with ksh88 (can only use 0..2^12-1 index), but bash allows indexes up to 2^63-1.

_encode_letters() {
    sed '
/[^a-z]/d
s/$/#e100t111a0001o0010i0011n0101s0110r0111h1010d00000l01000u10110c10111/
s/$/m11000f11001y11011w000010g000011p010010b010011v110101k1101000/
s/$/x110100100q110100101j110100110z110100111/
:a
s/\([a-z]\)\(.*\)\(#.*\1\([01]\{1,\}\).*\)/\4\2\3/g
t a
s/#.*//
'
}
 
dict_put() {
    local k="$1"; shift
    local c="$(echo "$k" | _encode_letters)"
    local -i h="$(echo "0 2 i $c p" | dc)"
    (( h > 0 )) || { echo "dict_put: bogus key [$k]" >&2; return 1; }
    _DICT[$h]="$k:$@"
}

dict_get() {
    local k="$1"
    local c="$(echo "$k" | _encode_letters)"
    local -i h="$(echo "0 2 i $c p" | dc)"
    [ "${_DICT[$h]:-}" ] || { echo "dict_get: no such key [$k]" >&2; return 1; }
    echo "${_DICT[$h]#*:}"
}

No comments: