获取数组的索引

获取数组的索引

我正在尝试获取在 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

相关内容