Last active
December 12, 2024 05:50
-
-
Save darkseid4nk/4de8a097ee981a207a3ba03e7ace6a14 to your computer and use it in GitHub Desktop.
Helper functions for workin with arrays/dicts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Most functions use direct referencing for dict compatibility and key referencing when indexes/keys may not be in a sequential numeric order. | |
# inarray is the only function that you expand the entire array as an argument i.e. "${_arr[@]}" | |
array_empty(){ | |
# array_empty "_arrayname" | |
# uses direct reference | |
# Returns 0 if an array is empty. Returns 1 otherwise | |
# Works on arrays and dicts | |
[[ "$#" -ne "1" ]] && return 1 | |
[[ "${!1@a}" != [aA] ]] && return 1 | |
local -n _arr=("${1}") | |
[[ -z "${_arr[@]}" ]] && return 0 || return 1 | |
} | |
array_end(){ | |
# array_end "_arrayname" | |
# uses direct reference | |
# Returns the value of the last element. Returns 1 if empty | |
# Works on arrays and dicts | |
[[ "$#" -ne "1" ]] && return 1 | |
[[ "${!1@a}" != [aA] ]] && return 1 | |
local -n _arr="${1}" | |
[[ "${#_arr[@]}" -eq "0" ]] && return 1 | |
local _keys=("${!_arr[@]}") | |
local _last_key="${_keys[-1]}" | |
printf "%s\n" "${_arr[$_last_key]}" | |
return 0 | |
} | |
array_key_exists(){ | |
# array_key_exists "key" "arrayordict_name" | |
# Uses direct reference. Cannot indirect reference dicts for keys. | |
# returns 0 if key exists in array. Otherwise returns 1. If array doesnt exist will return 1 | |
# Works on arrays and dicts | |
[[ "$#" -ne "2" ]] && return 1 | |
[[ "${!2@a}" != [aA] ]] && return 1 | |
local _key="$1" | |
local -n _arr="$2" | |
[[ "${!_arr[@]}" =~ "${_key}"( |$) ]] && return 0 || return 1 | |
} | |
array_key_first(){ | |
# array_key_first <arrayordict_name> | |
# Uses direct reference. Cannot indirect reference dicts for keys. | |
# returns first key of array, otherwise returns 1 on empty | |
# Works on arrays and dicts | |
[[ "$#" -ne 1 ]] && return 1 | |
[[ "${!1@a}" != [aA] ]] && return 1 | |
local -n _arr="$1" | |
local _keys=("${!_arr[@]}") | |
[[ -z "${_keys[0]}" ]] && return 1 | |
printf "%s\n" "${_keys[0]}" | |
return 0 | |
} | |
array_key_last(){ | |
# array_key_last <arrayordict_name> | |
# Uses direct reference. Cannot indirect reference dicts for keys. | |
# returns last key of array, ootherwise returns 1 | |
# Works on arrays and dicts | |
[[ "$#" -ne 1 ]] && return 1 | |
[[ "${!1@a}" != [aA] ]] && return 1 | |
local -n _arr="$1" | |
local _keys=("${!_arr[@]}") | |
[[ "${#_keys[@]}" -eq 0 ]] && return 1 | |
printf "%s\n" "${_keys[-1]}" | |
return 0 | |
} | |
in_array(){ | |
# in_array <needle> "${array_name[@]}" | |
# Expands entire array as function argument. Splits by | | |
# Searches for needle in haystack | |
# returns 0 if found, returns 1 otherwise. | |
# Works on arrays and dicts | |
joinByChar() { local IFS="$1"; shift; echo "$*"; } | |
shopt -s extglob | |
local element="$1" | |
shift | |
local array=("$@") | |
[[ "$element" == @($(joinByChar '|' "${array[@]//|/\\|}")) ]] && return 0 || return 1 | |
} | |
array_pop(){ | |
# array_pop <array_name> | |
# Uses direct reference to array | |
# pop element off the end of array | |
# returns the value of the last element of array, null if empty, returns 1 otherwise. | |
# Works on arrays and dicts | |
[[ "$#" -ne "1" ]] && return 1 | |
[[ "${!1@a}" != [aA] ]] && return 1 | |
local -n _arr="$1" | |
local _keys=("${!_arr[@]}") | |
[[ "${#_keys[@]}" -eq 0 ]] && return 1 | |
local _lastkey="${_keys[-1]}" | |
local _lastval="${_arr[$_lastkey]}" | |
unset _arr[${_lastkey}] | |
printf "%s\n" "${_lastval}" | |
return 0 | |
} | |
array_push(){ | |
# array_push <array_name> <string> | |
# push element onto the end of array | |
# Only works on arrays | |
[[ "$#" -ne "2" ]] && return 1 | |
[[ "${!1@a}" != [a] ]] && return 1 | |
local -n _arr="$1" | |
local _str="$2" | |
_arr[${#_arr[@]}]="${_str}" | |
return 0 | |
} | |
array_search(){ | |
# array_search <array_name> <string> | |
# Uses direct reference for compatibility with dicts. | |
# searches array for a given value and returns the first corresponding key if successful | |
# Otherwise return 1 | |
# Works on arrays and dicts | |
[[ "$#" -ne "2" ]] && return 1 | |
[[ "${!1@a}" != [aA] ]] && return 1 | |
local -n _arr="$1" | |
local _pattern="$2" | |
local key | |
for key in "${!_arr[@]}"; do | |
if [[ "${_arr[$key]}" =~ "$_pattern" ]]; then | |
printf "%s" "$key" | |
return 0 | |
fi | |
done | |
return 1 | |
} | |
array_shift(){ | |
# array_shift <array_name> | |
# shift an element off the beginning of array | |
# returns the shifted value, or null if array is empty or is not an array | |
# Works on arrays and dicts | |
[[ "$#" -ne "1" ]] && return 1 | |
[[ "${!1@a}" != [aA] ]] && return 1 | |
local -n _arr="$1" | |
local -a _keys=("${!_arr[@]}") | |
local _firstkey="${_keys[0]}" | |
[[ -z "${_firstkey}" ]] && return 1 | |
local _firstvalue="${_arr[${_firstkey}]}" | |
unset _arr[$_firstkey] | |
printf "%s\n" "${_firstvalue}" | |
return 0 | |
} | |
array_start(){ | |
# array_start <array_name> | |
# Returns the value of the first element or false for empty array. | |
# Works on arrays and dicts | |
[[ "$#" -ne "1" ]] && return 1 | |
[[ "${!1@a}" != [aA] ]] && return 1 | |
local -n _arr="$1" | |
local -a _keys=("${!_arr[@]}") | |
local _firstkey="${_keys[0]}" | |
[[ -z "${_firstkey}" ]] && return 1 | |
local _firstvalue="${_arr[${_firstkey}]}" | |
printf "%s\n" "${_firstvalue}" | |
return 0 | |
} | |
array_unshift(){ | |
# array_unshift <array_name> <string> | |
# pushes element onto the beginning of array | |
# Only works on arrays, not dicts. | |
[[ "$#" -ne "2" ]] && return 1 | |
[[ "${!1@a}" != [a] ]] && return 1 | |
local -n _arr="$1" | |
local _str="$2" | |
_arr=("${_str}" "${_arr[@]}") | |
return 0 | |
} | |
array_strlen(){ | |
# All 4 options are required to be passed. | |
# -m | mode=long or short, this will return the longest string or the shortest string | |
# -r | <string>. String name of array we are getting strlen from. This creates a reference to the array. (cant pass arrays in bash) | |
# -t | type=word or string. This defines whether we want to count the entire string value, or each word in each value (whitespace separation) | |
# -s | select=key or value. This defines whether we are getting the strlen the keys in the associative array, or the values | |
local -A _s | |
OPTIND=1 | |
while getopts ":t:m:r:s:" opt; do | |
case ${opt} in | |
m) [[ "${OPTARG}" =~ ^(short)$|^(long)$ ]] && _s[m]="$(printf "sort -n%s" $([ -n "${BASH_REMATCH[2]}" ] && echo "r"))";; | |
r) local -n _ref="${OPTARG}" && [[ "${_ref@a}" =~ (A|a) ]] && _s[ref]=true;; | |
s) [[ "${OPTARG}" =~ ^(key|value)$ ]] && _s[s]="${OPTARG}";; | |
t) [[ "${OPTARG}" =~ ^(word|string)$ ]] && _s[t]="${OPTARG}";; | |
:) return 1;; | |
?) return 1;; | |
esac | |
done | |
[ "${#_s[@]}" -ne 4 ] && return 1 | |
local -a _value_lengths | |
if [ "${_s[s]}" = "key" ] && [ "${_ref@a}" = "A" ]; then _iterate_arr=("${!_ref[@]}"); else _iterate_arr=("${_ref[@]}"); fi | |
[ "${_s[t]}" = "word" ] && IFS=$' ' || IFS=$'\n' | |
for str in ${_iterate_arr[@]}; do _value_lengths+=("${#str}"); done | |
IFS=$'\n' _array_val_largest=$(echo "${_value_lengths[*]}" | eval ${_s[m]} | head -n1) | |
echo "${_array_val_largest}" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment