Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
changeset 522:210695c732dd
array.sh: Implement alist_for_each().
This is analogous to array_for_each().
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 02 Sep 2024 02:12:07 +0200 |
| parents | c05ef1c86c9c |
| children | ea199195b214 |
| files | share/local-bsdtools/array.sh |
| diffstat | 1 files changed, 62 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/share/local-bsdtools/array.sh Sun Sep 01 21:52:01 2024 +0200 +++ b/share/local-bsdtools/array.sh Mon Sep 02 02:12:07 2024 +0200 @@ -1048,7 +1048,7 @@ __farr_varname=$1 [ $# -lt 2 ] && _farr_fatal "missing array name" __farr_name=$2 - __farr_val_array=${_farr_alist_value_infix}${__farr_name} + __farr_val_array=${_farr_alist_value_infix}${__farr_name} [ $# -lt 3 ] && _farr_fatal "missing index" __farr_index=$3 @@ -1087,6 +1087,61 @@ #: +#: Call a function for every key-value pair in an alist starting in index order. +#: +#: The function to be called must accept three or four arguments: +#: - the alist name +#: - the element key at the current index +#: - the element value at the current index +#: - the current index +#: +#: The iteration stops if the called function returns a falsy value. +#: +#: Args: +#: $1 (str): The name of an existing array. +#: $2 (str): The name of a function to be called with four arguments. +#: +#: Warning: +#: If the number of elements changes while being in `alist_for_each` then +#: the behaviour is undefined. +#: The current implementation determines the length of the alist once +#: at the start of execution. +#: +alist_for_each() { + local __farr_name __farr_callback + + local __farr_key_array __farr_val_array __farr_idx __farr_length + local __farr_feidx __farr_fekey __farr_feval __farr_rv + + [ $# -lt 1 ] && _farr_fatal "missing alist name" + __farr_name=$1 + __farr_key_array=${_farr_alist_key_infix}${__farr_name} + __farr_val_array=${_farr_alist_value_infix}${__farr_name} + [ $# -lt 2 ] && _farr_fatal "missing callback function name" + __farr_callback="$2" + + if ! alist_length __farr_length ${__farr_name}; then + _farr_fatal "alist \`${__farr_name}' does not exist" + fi + __farr_feidx=1 + while [ ${__farr_feidx} -le ${__farr_length} ]; do + if alist_tryget_key_at_index __farr_fekey ${__farr_name} ${__farr_feidx}; then + if alist_tryget_value_at_index __farr_feval ${__farr_name} ${__farr_feidx}; then + eval "${__farr_callback} ${__farr_name} \"\${__farr_fekey}\" \"\${__farr_feval}\" ${__farr_feidx}" + __farr_rv=$? + [ ${__farr_rv} -ne 0 ] && return ${__farr_rv} + else + _farr_fatal "alist \`${__farr_name}': missing value index" + fi + else + _farr_fatal "alist \`${__farr_name}': missing key index" + fi + __farr_feidx=$((${__farr_feidx} + 1)) + done +} + + +#: #: Print the contents of an alist to stderr. #: #: Args: @@ -1233,7 +1288,7 @@ echo "VALID LENGTH (ERROR)" fi - # Iteration + # Iteration by indexing echo "ITERATE:" _i=1 while alist_tryget_key_at_index _k LIST ${_i}; do @@ -1242,7 +1297,11 @@ printf " KEY: \`%s', VAL: \`%s'\\n" "${_k}" "${_v}" _i=$((${_i} + 1)) done - + + # Iteration with for each + echo "ITERATE (for each):" + alist_for_each LIST $'printf "EACH: %s key \\`%s\\\', value \\`%s\\\' at idx %d\\n"' # ` + alist_clear LIST if ! alist_destroy LIST ; then echo "DESTROY FAILED (ERROR)"
