Home > Software engineering >  How can I get what element is a value in an array from whether it matches a value?
How can I get what element is a value in an array from whether it matches a value?

Time:07-04

I have a variable value which is 25. I want to search for that variable in an array with several elements and get the position in my array that matches the value of my variable. In this example, I should get that what I am looking for is position 3 as the 25 matches my variable. When it finds the value I want to store it in a variable so my result variable should be 3.

value=25
array=( 11 13 17 25 36 )
result=0

My idea is to go through the array with a for loop and if it finds the value it stores it in another variable. This is what I tried:

for i in ${array[@]}; do
   if [[ $i -eq $value ]]; then
      result=$i
   fi
done

But this returns 25 and not its position, how can I return its position in the array?

CodePudding user response:

You can do something like this:

Assuming your array has only positive integers, declared result=-1 so that it prints -1 if no match is found.

Use a separate variable like index.

And increment its value by 1 as the loop progresses forward.

value=25
array=( 11 13 17 25 36 )
result=-1
index=0
for i in ${array[@]}; do
   if [[ $i -eq $value ]]; then
      result=$index
      
   fi
   index=$((index 1))
done

echo $result

CodePudding user response:

You can iterate through the indexes of an array :

value=25
array=( 11 13 17 25 36 )
result=-1

for i in "${!array[@]}"; do
    if [[ "${array[i]}" -eq "$value" ]]; then
        result=$i
    fi
done
echo $result

CodePudding user response:

$ value=25
$ array=( 11 13 17 25 36 )

$ result=$(sed -En "s/.*\[([0-9]*)\]=\"$value\".*/\1/p" <(declare -p array))
$ echo $result 
3

CodePudding user response:

If you'll be doing that kind of lookup more than once, and assuming all of your values are unique (e.g. 25 doesn't appear multiple times), consider creating and using an associative array that contains the reverse mapping of values to indices so you only need to loop once to create that array and then every time you need to find the index of a value, it's just a fast hash lookup instead of a slow loop:

$ cat tst.sh
#!/usr/bin/env bash

value=$1

array=( 11 13 17 25 36 )
result=0

for i in "${!array[@]}"; do
    rev_array["${array[$i]}"]="$i"
done

[[ -v rev_array["$value"] ]] && result=${rev_array["$value"]}

echo "$result"

$ ./tst.sh 25
3

$ ./tst.sh foo
0

It sounds like you might be doing something that would be better written in awk anyway though.

  • Related