zsh: 연관 배열 길이를 얻는 방법은 무엇입니까?

zsh: 연관 배열 길이를 얻는 방법은 무엇입니까?

배열에 관한 다른 기사에서 볼 수 있듯이 다음을 시도했습니다.

test[1]="hello"
test[7]="foo"
test[3]="world"
echo ${#test[@]}
7

하지만 그것은 나에게 연관 배열의 마지막 인덱스를 제공합니다.

연관 배열의 길이를 얻는 방법은 무엇입니까?

답변1

이것을 미리 실행하지 않는 한 typeset -A test, 연관 배열이 아닌 일반 배열의 요소가 할당됩니다.

대부분의 쉘 및 언어의 배열과 같은 zsh 배열(내가 알고 있는 유일한 예외는 ksh(및 ksh 배열 디자인을 복사하는 bash)입니다)은 희박하지 않습니다.

인덱스 2의 요소를 6으로 설정하지 않고 인덱스 1과 7의 요소를 설정하면 7개 요소의 배열이 여전히 할당되며 요소 2~6은 빈 문자열로 설정됩니다.

따라서 이 코드는 다음과 같습니다.

test=(hello '' world '' '' '' foo)

다음을 통해 확인할 수 있습니다.

$ typeset -p test
typeset -a test=( hello '' world '' '' '' foo )

이제 다음을 사용하세요.

$ typeset -A test
$ test[1]=hello test[7]=foo test[3]=world test[03]=zeroworld

그것은 같은

typeset -A test=(
  1  hello
  7  foo
  3  world
  03 zeroworld
)

최신 버전은 다음도 지원합니다.

typeset -A test=(
   [1]=hello
   [7]=foo
   [3]=world
  [03]=zeroworld
)

ksh93/bash와의 호환성을 위해.

이를 연관 배열로 정의할 수 있습니다(키는 숫자가 아닌 임의의 바이트 시퀀스입니다. 원하는 경우 이를 숫자로 해석할 수 있습니다).

$ print -r -- $#test $test[3] $test[03]
4 world zeroworld

일반 배열에서 비어 있지 않은 문자열의 요소 수를 계산하려면 다음을 수행할 수 있습니다.

$ typeset -a test=()
$ test[1]=hello test[7]=foo test[3]=world
$ (){print $#} $test
3

이는 따옴표가 없는 매개변수 확장이 빈 요소를 제거한다는 사실에 의존합니다(ksh와의 호환성을 돕기 위해).

비교:

$ (){print $#} "$test[@]"
7

(Bourne 쉘과 유사 "$@") 삭제하지 않습니다.

${array:#pattern}패턴과 일치하는 요소를 제거하는 연산자를 사용하여 명시적으로 제거 할 수도 있습니다 .

$ (){print $#} "${test[@]:#}"
3

이는 ${#array[@]}Korn 쉘 구문입니다. 에서는 zshcsh와 마찬가지로 사용할 수 있습니다 $#array(Korn 구문도 지원하지만).

관련 정보