Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Consider I have a very large array $large_list, is there a way to write a function that will take the array as an argument? For example:

echo_idx_array () {
    arr="$1"
    idx="$2"

    echo "${arr[$idx]}"
}

What is the usual strategy to do something like that? I tried giving the variable $large_list but it was empty.

I am willing to modify the function to adapt it to any change in the argument list.

For the record, I am using ksh88, and I am looking for answers as portable as can be.


EDIT: So far the best I could come up with is to loop through the array and send each element as an argument to the function. This seems incredibly ugly and error-prone, not to mention that it is bound to hit some limit quickly. Here's what I did:

foo () {
    echo $*
}

cmd="foo "
while [[ $i -lt $MAX_ARR_SIZE ]]; do
    cmd="$cmd ${large_list[$i]}"
    ((i=i+1))
done

eval $cmd

Isn't there something better to do?

share|improve this question
1  
I'm not familiar with ksh88, but if you need to pass the entire array by value, have you tried func "${array[@]}"? If you only need to pass one element, just pass the element - no need to make it more convoluted by passing an array and an index. –  jw013 Jun 22 '12 at 12:14
    
I tried the syntax you suggested, but it did not work :( –  rahmu Jun 22 '12 at 12:29
1  
I was tired and confused. I had tried "${array[$@]}. Your suggestion actually works. Mea culpa. –  rahmu Jun 26 '12 at 15:11

2 Answers 2

up vote 5 down vote accepted

To pass the array elements as arguments to the function, use the ksh syntax to expand the elements of the array as a list.

work_on_array "${myarray[@]}"

The [@] suffix makes this an array expansion. The double quotes protect each element from further expansion (splitting and globbing). The result of the expansion is not in general one word like it usually is with double quotes, but as many words as there are elements in the array.

The Nth element of the array is then ${N}. To access it, you need to use eval; see Use a variable reference "inside" another variable

share|improve this answer
    
Thanks. Question: if the result of the expansion is not one word, why are the quotes needed? Can they be omitted? Are you just applying your advice of "always quote unless you have a good reason not to"? :p –  rahmu Jun 23 '12 at 10:16
1  
@rahmu The quotes are needed to avoid splitting and globbing on individual elements. Consider myarray=("hello world" wibble) (2 elements, the first of which contains a space): work_on_array "${myarray[@]}" passes 2 parameters hello world and wibble; work_on_array ${myarray[@]} passes 2 parameters hello, world and wibble. And with myarray=(*), work_on_array ${myarray[@]} passes the list of files in the current directory. (Hence this is one of the many cases where my advice makes a practical difference.) –  Gilles Jun 23 '12 at 21:47
    
Correct me if I'm wrong, but I believe there's a typo in what you wrote: the unquoted expansion passes 3 params, not 2. –  rahmu Jun 23 '12 at 22:40
    
@rahmu There are two parameters: fear and surprise… and ruthless efficiency. (In other words, you're right, there's a typo: hello, world and wibble make 3 parameters.) –  Gilles Jun 23 '12 at 22:56

Depends on the Korn Shell… recent AT&T ksh93 and mksh versions support this:

function echo_idx_array {
    nameref arr=$1
    idx=$2

    echo "${arr[idx]}"
}

set -A test -- a b c
echo_idx_array test 1

In my current shell, this does output “b”.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.