Is In array test and some other quick arrays functions
Comming something late on this post, I would add here some efficients tricks I use on small array (upto some megabytes anyway).
1. IsInArray as requested:
is_in_array() {
local IFS=$'\1' _value="$1"
shift
case "$IFS$*$IFS" in
*"$IFS$_value$IFS"* ) return 0;;
*) return 1;;
esac
}
As this function don't use fork nor loop, this is the quickest way:
array_test=("text1" text2 text3 "text4" text5 "Hello world." $'Text with a\nnewline.')
for val in text4 text12 'Hello world.' $'Some\nstring' $'Text with a\nnewline.';do
if is_in_array "$val" "${array_test[@]}"; then
echo ${val@Q} is present in \$array_test.
else
echo ${val@Q} is not present in \$array_test.
fi
done
'text4' is present in $array_test.
'text12' is not present in $array_test.
'Hello world.' is present in $array_test.
$'Some\nstring' is not present in $array_test.
$'Text with a\nnewline.' is present in $array_test.
This use \1
as IFS separator in order to be able to work with strings that contain spaces or even newlines.
2. Array length
to show the length of an array:
echo ${#array_test[@]}
7
will show the number of element in array,
2.1 Array length in chars
echo ${#array_test}
5
will show the length of the 1st element
echo ${#array_test[-1]}
20
will show the length of the last element
: "${array_test[*]}"; echo ${#_}
63
will show the total length of array,
As unicode characters could hold more than one byte, this could be usefull:
printf -v _ '%s%n' "${array_test[0]}" val; echo $val
5
Yes, this is not really easy to read, i little counter-intuitive, but this is the quickest ways (tried to play with local LANG=C
in a function but this goes slower).
printf -v
tell to create a variable _
which is a garbage
%n
is a rare printf
option that tell printf to store current
output pointer to next argument which have to be a variable name.
printf -v _ '%s%n' "$array_test" val;echo $val
5
will show the length of the 1st element
printf -v _ '%s%n' "${array_test[-1]}" val;echo $val
20
will show the length of the last element, and
printf -v _ '%s%n' "${array_test[*]}" val; echo $val
63
array_test+=('déjà vu')
printf -v _ '%s%n' "${array_test[*]}" val
: "${array_test[*]}"
echo Whole array is $val bytes but ${#_} character length.
Whole array is 73 bytes but 71 character length.
will show the total length of array,
3. dump reusable variable
I sometime use this for transporting arrays:
printf -v string '[%%d]=%q ' "${array_test[@]}"
printf -v string "$string" "${!array_test[@]}"
echo "$string"
[0]=text1 [1]=text2 [2]=text3 [3]=text4 [4]=text5 [5]=Hello\ world. [6]=$'Text w
ith a
newline.' [7]=déjà\ vu
which could be reused:
declare -a "newVar=($string)"
declare -p newVar
declare -a newVar=([0]="text1" [1]="text2" [2]="text3" [3]="text4" [4]="text5" [
5]="Hello world." [6]=$'Text with a\nnewline.' [7]="déjà vu")
for
loop to iterate over the indices (assuming the array isn't too sparse):for((i=0; i<=${#array[@]}; i++)); do item=${array[i]}; ...; done
. This is because the shell does not need to fully expand the array before starting the search. – Escallop