2

Is there a way to pass an array to a function as one of its parameters?

Currently I have

#!/bin/bash
highest_3 () {
  number_under_test=(${array[@]})
  max_of_3=0
  for ((i = 0; i<$((${#number_under_test[@]}-2)); i++ )) { 
    test=$((number_under_test[i] +
      number_under_test[i+1] +
      number_under_test[i+2]))
    if [ $test -gt $max_of_3 ]; then
      max_of_3=$((number_under_test[i]+
        number_under_test[i+1]+
        number_under_test[i+2]))
      result=$((number_under_test[i]))$((number_under_test[i+1]))$((number_under_test[i+2]))
    fi
  } 
}
array=(1 2 3 4 5 6 7 8 7 6 5 4 3 2 1)
highest_3
echo result=$result
array=(1 2 3 4 3 2 1)
highest_3
echo result=$result

which works by just setting array and using array, but is there a way to pass in the array, e.g. (1 2 3 4 5 4 3 2 1) as an actual parameter rather than just setting a (presumably global) variable?

Update: I'd like to be able to pass in other parameters beside this array

3 Answers 3

6

You can always pass the array to the function and rebuild it as an array within the function:

#!/usr/bin/env bash

foo () {
    ## Read the 1st parameter passed into the new array $_array
    _array=( "$1" )
    ## Do something with it.
    echo "Parameters passed were 1: ${_array[@]}, 2: $2 and 3: $3"

}
## define your array
array=(a 2 3 4 5 6 7 8 7 6 5 4 3 2 1)
## define two other variables
var1="foo"
var2="bar"

## Call your function
foo "$(echo ${array[@]})" $var1 $var2

The script above produces the following output:

$ a.sh
Parameters passed were 1: a 2 3 4 5 6 7 8 7 6 5 4 3 2 1, 2: foo and 3: bar
1
  • 3
    But the array is not the same inside of foo(). In main, your ${#array[@]} results to 15 elements, but in foo() ${#_array[@]} shows just 1 element. See also here. Commented Sep 21, 2017 at 16:36
3

You could read the arguments inside the function as an array. And then invoke the function with those arguments. Something like this worked for me.

#!/bin/bash

highest_3 () {
number_under_test=("$@")
max_of_3=0
for ((i = 0; i<$((${#number_under_test[@]}-2)); i++ )) { 
 test=$((number_under_test[i] +
  number_under_test[i+1] +
  number_under_test[i+2]))
if [ $test -gt $max_of_3 ]; then
  max_of_3=$((number_under_test[i]+
    number_under_test[i+1]+
    number_under_test[i+2]))
  result=$((number_under_test[i]))$((number_under_test[i+1]))$((number_under_test[i+2]))
fi
} 
echo $result
}

highest_3 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1

# or
array=(1 2 3 4 5 6 7 8 7 6 5 4 3 2 1)
highest_3 "${array[@]}"
3
  • +1 Would there also be a way to pass in other parameters? Is the only way to have their positions specified, e.g. p1 is x, p2 is y and p3-p10 are the array elements? Thx! Commented Feb 8, 2015 at 14:07
  • 1
    You could take a look at getopts - wiki.bash-hackers.org/howto/getopts_tutorial. I'll see if I can get a sample working. Commented Feb 8, 2015 at 14:16
  • @MichaelDurrant - no, when you work with an arg array you shift or otherwise iterate over it. Like fn() for arg do echo "$arg"; done; fn 1 2 3 4 Commented Feb 8, 2015 at 16:03
1

You can pass only strings as arguments. But you could pass the name of the array:

highest_3 () {
  arrayname="$1"
  test -z "$arrayname" && exit 1
  # this doesn't work but that is the idea: echo "${!arrayname[1]}"
  eval echo '"${'$arrayname'[1]}"'
}
1
  • You can do the indirect thing, but you have to store the ! in the value. Commented Feb 8, 2015 at 21:59

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.