配列の元の順序と逆の順序を同時に取得するには?

配列の元の順序と逆の順序を同時に取得するには?

arrそれでは、2つの要素からなる配列があるとしましょう。

read -a arr <<< "$@"

その後、関数またはスクリプトでそれを使用し、次のように2つの文字列または要素を入力できます。

read_me() {
read -a arr <<< "$@"
}
read_me "first test"

これで、配列のすべての要素を取得する方法がわかりました。

for i in "${arr[@]}"
do
    echo "$i" # where i do something with the respective element of said array.
done

ただし、これは前述の配列に要素が追加される通常の/元の順序でのみ実行できます。もちろん、配列の要素を逆順に取得する方法も知っています。

indices=( ${!arr[@]} )
for ((i=${#indices[@]} - 1; i >= 0; i--)) ; do
    echo "${arr[indices[i]]}"
done

どちらの方法も期待どおりに機能します。しかし、問題は正順と逆順が必要だということです。同じループで。ほとんどの場合、これを行う必要はありません。

echo "${arr[0]}" "${arr[1]}"
echo "${arr[1]}" "${arr[0]}"

ループでこれを行うにはどうすればよいですか?

ベストアンサー1

array=( 1 2 3 a b c )

for i in "${!array[@]}"; do
    j=$(( ${#array[@]} - i - 1 ))
    printf '%s\t%s\n' "${array[i]}" "${array[j]}"
done

出力:

1       c
2       b
3       a
a       3
b       2
c       1

つまり、現在のインデックスに基づいて新しいインデックスを計算して使用しながら、どの順序でも配列を繰り返すのを防ぐ方法はありません。


質問に対するコメントの中には、次のようなものがあります。提案次の算術ループの場合:

for (( i = 0, j = ${#array[@]} - 1; i < ${#array[@]}; ++i, --j ))
do
    printf '%s\t%s\n' "${array[i]}" "${array[j]}"
done

これは、ループヘッダーの初期化および更新部分でコンマ演算子を使用して維持できるという事実を利用します。二つ別々のループ変数。


達成したい目標と実際の配列値に応じて、以下を使用することもできますtac

$ paste <( printf '%s\n' "${array[@]}" ) <( printf '%s\n' "${array[@]}" | tac )
1       c
2       b
3       a
a       3
b       2
c       1

おすすめ記事