changeset 745:a5918c859fe9

farray.sh: Implement falist_find() -- a variant of falist_contains() that also returns the found index proper
author Franz Glasner <fzglas.hg@dom66.de>
date Tue, 08 Oct 2024 17:55:23 +0200
parents 93ff221b9c35
children 7e2279d6db0f
files share/local-bsdtools/farray.sh tests/farray-alist.t
diffstat 2 files changed, 66 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/share/local-bsdtools/farray.sh	Tue Oct 08 16:11:52 2024 +0200
+++ b/share/local-bsdtools/farray.sh	Tue Oct 08 17:55:23 2024 +0200
@@ -2695,6 +2695,66 @@
 
 
 #:
+#: Try to find the index of a given key in an alist.
+#:
+#: Args:
+#:   $1 (str): The name of a variable where to put the found index into
+#:   $2 (str): The existing alist.
+#:   $3: The key.
+#:   $4 (int, nuĺl, optional): The start index to search for (inclusive).
+#:                             If not given or `null` then `1` is used.
+#:   $5 (int, null, optional):  The index to stop (inclusive).
+#:                              If not given or `null` then the length of
+#:                              `$2` is used.
+#:
+#: Returns:
+#:   0 (truthy) on success if the key is found,
+#:   1 (falsy) if the given key is not found.
+#:
+falist_find() {
+    local __farr_varname __farr_name __farr_key
+    local __farr_start __farr_end
+
+    local __farr_token __farr_objname __farr_keyname __farr_valname __farr_len
+    local __farr_cur_find_idx __farr_fikey
+
+    __farr_varname="${1-}"
+    [ -z "${__farr_varname}" ] && _farr_fatal "missing variable name"
+    shift
+
+    _farr_alist_get_meta "$@"
+    [ $# -lt 2 ] && _farr_fatal "missing key"
+    __farr_key="$2"
+
+    __farr_start="${3-}"
+    [ -z "${__farr_start}" ] && __farr_start=1
+    _farr_make_index __farr_start "${__farr_start}" "${__farr_len}"
+    [ ${__farr_start} -lt 1 ] && _farr_fatal "start index must be >= 1"
+    __farr_end="${4-}"
+    [ -z "${__farr_end}" ] && __farr_end="${__farr_len}"
+    _farr_make_index __farr_end "${__farr_end}" "${__farr_len}"
+    [ ${__farr_end} -lt 1 ] && _farr_fatal "end index must be >= 1"
+    [ ${__farr_end} -gt "${__farr_len}" ] && _farr_fatal "end index exceeds array length"
+
+    __farr_cur_find_idx=${__farr_start}
+    while [ ${__farr_cur_find_idx} -le ${__farr_end} ]; do
+        eval __farr_fikey=\"\$\{${__farr_keyname}_${__farr_cur_find_idx}+SET\}\"
+        if [ -n "${__farr_fikey}" ]; then
+            eval __farr_fikey=\"\$\{${__farr_keyname}_${__farr_cur_find_idx}\}\"
+            if [ "${__farr_fikey}" = "${__farr_key}" ]; then
+                eval "${__farr_varname}"=${__farr_cur_find_idx}
+                return 0
+            fi
+        else
+            _farr_fatal "key unexpectedly unset (index ${__farr_cur_find_idx})"
+        fi
+        __farr_cur_find_idx=$((__farr_cur_find_idx + 1))
+    done
+    return 1
+}
+
+
+#:
 #: Internal helper to delete an item from an alist storage.
 #:
 #: Args:
--- a/tests/farray-alist.t	Tue Oct 08 16:11:52 2024 +0200
+++ b/tests/farray-alist.t	Tue Oct 08 17:55:23 2024 +0200
@@ -74,8 +74,8 @@
   $ check_no_alist_artifacts
 
 
-Get / Set / Contains
-====================
+Get / Set / Contains / Find Index
+=================================
 
   $ falist_create LIST
   $ falist_set LIST K1 V1
@@ -108,8 +108,12 @@
   3 (no-eol)
 
   $ falist_contains LIST K1
+  $ falist_find idx LIST K1
+  $ test "$idx" -eq 1
   $ falist_contains LIST K
   [1]
+  $ falist_find idx LIST K
+  [1]
   $ falist_get _var LIST K2
   $ echo "$_var"
   V2 2