Reputation: 9708
This is my code:
function get_index() {
my_array="$1"
value="$2"
for i in "${!my_array[@]}"; do
if [[ "${my_array[$i]}" = "${value}" ]]; then
echo "was found"
echo "${i}";
fi
done
return -1
}
echo "index test"
get_index "${cut_pages[@]}" 5
index=$?
echo $index
The array includes 2
and 5
It must return 1, but it returns 255
What's the problem?
Upvotes: 1
Views: 1673
Reputation: 19685
Expanding on other answers, here are featured functions to handle a value at multiple indexes; and to handle multiples values at multiple indexes, with returning result to an array:
#!/usr/bin/env bash
function get_indexes() {
local -n my_array="$1" # use -n for a reference to the array
local -a indx=()
local -i rc=1
for i in "${!my_array[@]}"; do
if [ "${my_array[i]}" = "$2" ]; then
indx+=("$i")
rc=0
fi
done
echo "${indx[*]}"
return $rc
}
function get_all_indexes() {
if [ $# -lt 3 ]; then
printf 'get_all_indexes input_array output_array values...\n' >&2
return 2
fi
local -n input_array="$1" # use -n for a reference to the array
shift
local -n output_array="$1"
shift
if ! [[ "$(typeset -p "${!output_array}")" =~ ^declare\ -A ]]; then
printf 'Output array %s must be an associative array!\n' "${!output_array}" >&2
return 2
fi
local -i rc=1
for i in "${!input_array[@]}"; do
for value; do
if [ "${input_array[$i]}" = "$value" ]; then
if [ ${#output_array[$value]} -eq 0 ]; then
output_array[$value]="$i"
else
printf -v output_array[$value] $'%s\3%s' "${output_array[$value]}" "$i"
fi
rc=0
fi
done
done
return $rc
}
echo "Testing multi indexes single value"
declare -a cut_pages=([3]=2 [7]=5 [1]=3 [0]=5)
typeset -p cut_pages
if indexes=$(get_indexes cut_pages 5); then
echo "found 5 at indexes:"
echo "$indexes"
fi
printf "\n\nTesting multi indexes multiple values output to array\n"
declare -A out_arr=()
declare -A in_arr=(
["first"]="hello"
["second"]="world"
["third"]="hello"
["fourth"]="you"
)
typeset -p in_arr
if get_all_indexes in_arr out_arr "hello" "world" "you"; then
for k in "${!out_arr[@]}"; do
printf 'Found %q at indexes:\n' "$k"
IFS=$'\3' read -r -a indexes <<<"${out_arr[$k]}"
printf '%q\n' "${indexes[@]}"
done
fi
Output result:
Testing multi indexes single value
declare -a cut_pages=([0]="5" [1]="3" [3]="2" [7]="5")
found 5 at indexes:
0 7
Testing multi indexes multiple values output to array
declare -A in_arr=([fourth]="you" [third]="hello" [first]="hello" [second]="world" )
Found world at indexes:
second
Found you at indexes:
fourth
Found hello at indexes:
third
first
Upvotes: 2
Reputation: 4718
You could use a name reference to the array instead of passing the whole array as individual arguments:
function get_index() {
local -n my_array=$1 # use -n for a reference to the array
for i in "${!my_array[@]}"; do
if [[ ${my_array[i]} = $2 ]]; then
printf '%s\n' "$i"
return
fi
done
return 1
}
cut_pages=( 1 2 3 4 5 )
index=$(get_index cut_pages 5) && echo "index=$index"
Upvotes: 3
Reputation: 782785
You can't pass an array as a single argument to a function. When you write "${cut_pages[@]}"
it spreads the array into separate arguments to the function.
I've changed the function to take the value to search for as the first argument, and the array is all the rest of the arguments. After assigning this to value
, the shift
command removes it from the argument list, and then I iterate over "$@"
to process the remaining arguments.
You're also not getting the result of the function correctly. $?
contains the status code in the return
statement. To get what the function echoes, you use $(...)
. I've removed echo "was found"
so this won't get into the result.
#!/bin/bash
function get_index() {
value="$1"
shift
local index=0
for i in "$@"; do
if [[ "$i" = "${value}" ]]; then
echo "${index}";
return
fi
((index++))
done
return 1
}
echo "index test"
cut_pages=(2 5)
if index=$(get_index 5 "${cut_pages[@]}"); then
echo $index
fi
Upvotes: 2