配列を関数に渡す最も正しい方法は何ですか?


8

私が非常に大きな配列を持っていると考えてください$large_list、配列を引数としてとる関数を書く方法はありますか?例えば:

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

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

そのようなことをするための通常の戦略は何ですか?変数を指定してみまし$large_listたが、空でした。

引数リストの変更に合わせて関数を変更するつもりです。

記録のために、私はksh88を使用しており、可能な限りポータブルな答えを探しています。


編集:これまでのところ私が思いつくことができる最善の方法は、配列をループして、各要素を関数の引数として送信することです。これは信じられないほど醜く、エラーが発生しやすいようです。言うまでもなく、すぐに制限に達します。これが私がしたことです:

foo () {
    echo $*
}

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

eval $cmd

何か良いことはありませんか?


1
私はksh88に精通していませんが、配列全体を値で渡す必要がある場合は、試しましたfunc "${array[@]}"か?1つの要素のみを渡す必要がある場合は、その要素を渡します。配列とインデックスを渡して複雑にする必要はありません。
jw013

あなたが提案した構文を試しましたが、うまく
いき

1
私は疲れて混乱しました。試してみました"${array[$@]}。あなたの提案は実際に機能します。Mea culpa。
rahmu

回答:


10

配列要素を引数として関数に渡すには、ksh構文を使用して配列の要素をリストとして展開します。

work_on_array "${myarray[@]}"

[@]接尾辞は、このアレイの拡張を行います。二重引用符は、各要素がさらに拡張されないように保護します(分割およびグロビング)。展開の結果は通常、通常は二重引用符で囲まれているような1つの単語ではなく、配列内の要素と同じ数の単語です。

配列のN番目の要素はです。これにアクセスするには、を使用する必要があります。別の変数の「内部」で変数参照使用するを参照してください${N}eval


ありがとう。質問:拡張の結果が1語でない場合、引用符が必要なのはなぜですか?省略できますか?「正当な理由がない限り常に引用する」というアドバイスを適用しているだけですか?:p
rahmu

1
@rahmu引用符は、個々の要素の分割とグロビングを回避するために必要です。myarray=("hello world" wibble)(2つの要素、最初の要素にはスペースが含まれる)を考えwork_on_array "${myarray[@]}"ます。2つのパラメータhello worldを渡しますwibblework_on_array ${myarray[@]}2つのパラメータを渡しhelloworldそしてwibble。そして、でmyarray=(*)work_on_array ${myarray[@]}カレントディレクトリ内のファイルのリストを渡します。(したがって、これは私のアドバイスが実際に違いをもたらす多くのケースの1つです。)
Gilles「SO-邪悪になるのをやめる」

私は間違っているんだけど、私はあなたが書いたものにタイプミスがあると信じているなら、私を修正してください:引用符で囲まれていない拡張が通る3つのparams、ない2
rahmu

1
@rahmu恐怖と驚き…そして冷酷な効率という2つのパラメーターがあります。(言い換えれば、あなたが正しい、タイプミスがあります:helloworldおよびwibble3つのパラメーターを作成します。)
Gilles「SO-邪悪なことをやめ

4

bash 4.3以降には、おそらくkshに由来する方法があります。

echo_idx_array () # array index
{
    local -n array=$1     # add nameref attribute
    local idx=$2
    echo "${array[idx]}"
}

$ names=(one two three four)
$ echo_idx_array names 2
three
$ days=([monday]=eggs [tuesday]=bread [sunday]=jam)    # associative array
$ echo_idx_array days sunday
jam

もご覧くださいdeclare -n


ええ、面白い。はい、これはkshからのもので、mkshで変更なしで動作します。
mirabilos 2014年

1

Korn Shellに依存します…最近のAT&T ksh93およびmkshバージョンはこれをサポートします:

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

    echo "${arr[idx]}"
}

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

私の現在のシェルでは、これは「b」を出力します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.