![배열의 인덱스 가져오기](https://linux55.com/image/102062/%EB%B0%B0%EC%97%B4%EC%9D%98%20%EC%9D%B8%EB%8D%B1%EC%8A%A4%20%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0.png)
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