forループで繰り返される配列のインデックスを取得しようとしています。私は次のようなことをしています。
arr=( foo bar baz )
for i in $arr; do
echo "index ${#arr}";
done
ただし、これは配列の現在の値の位置ではなく、配列内の要素の数だけを提供します。どうすればいいですか?
答え1
誰も明確な答えを持っていないようだからそうします。
なぜCやJavaなどの主流言語で使用される数値forループを使用しないのですか?
for ((i = 1; i <= $#arr; i++)); do
echo "Index: $i, value: ${arr[i]}"
done
あるいは、より短いかもしれません(大規模な配列の場合はより遅く、潜在的にメモリ集約的です)。
for i in {1..$#arr}; do
echo "Index: $i, value: ${arr[i]}"
done
答え2
配列リテラル一致と現在のインデックスを返すフラグを使用してこれを実行できます。
arr=( foo bar baz )
for i in $arr; do
echo "index ${arr[(ie)$i]}";
done
このi
フラグはインデックスを返し、このe
フラグはi
文字通り文字列と一致するように動作を変更します。式は次のとおりです。 for arrは文字列$ iと一致し、文字通りインデックスを返します。この方法の欠点は、配列のすべての要素が一意である場合にのみ信頼できることです。それ以外の場合は、一種のカウンターを使用する必要があります。
答え3
zsh 5.0.6以降、配列を拡張し、圧縮でインデックスを作成できます。
for k v in "${(@)${=${(eQ):-'$( (( $#ary )) && echo {1..$#ary})'}}:^ary}"; do
[[ -z $k ]] && continue
echo "index: $k - value: $v"
done
私は実際にそれを使用しません(将来、ナイフに刺すのを恐れて)、多くの要素を持つ配列の場合は遅くなります。 zshの配列はリーンできないので、カウンタを増やす方が効率的です。
答え4
「実用的な」同等です(説明の制限を参照)が、lluaが実行するほとんどの作業を実行するより簡単な方法は、貼り付けと手続き型置換を使用します。
arr=( foo "bar 't' ttt" baz )
paste <(echo {1..$#arr}"\n") <(echo ${^arr}"\n") | head -n -1 | while read i v; do
echo index $i, val : $v;
done
編集:これは古いバージョンのzshで動作し、スペースと引用符を処理します。 (もちろん、forを使用しませんが、タスクに「forループ」の代わりに「繰り返し」と表示されます。
arr=( foo "bar 't' ttt" baz )
paste <(echo {1..$#arr}"\n") <(echo ${^arr}"\n") | head -n -1 | while read i v; do
echo index $i, val : $v;
done