As seen in another post for arrays, I tried this:
test[1]="hello"
test[7]="foo"
test[3]="world"
echo ${#test[@]}
7
But it gives me the last index of the associated array.
How to get the length of my associated array?
Unless you had run typeset -A test
beforehand, that will have assigned elements of a plain array, not an associative array.
zsh arrays like the arrays of most shells and languages (the only exception that I know is ksh (and bash which copied ksh's array design)) are not sparse.
If you set elements of index 1 and 7 without setting the elements of index 2 to 6, that will still allocate an array with 7 elements, the ones from 2 to 6 being set to the empty string.
So, that code is equivalent to:
test=(hello '' world '' '' '' foo)
You can confirm it with:
$ typeset -p test
typeset -a test=( hello '' world '' '' '' foo )
Now, with:
$ typeset -A test
$ test[1]=hello test[7]=foo test[3]=world test[03]=zeroworld
same as
typeset -A test=(
1 hello
7 foo
3 world
03 zeroworld
)
Recent versions also support:
typeset -A test=(
[1]=hello
[7]=foo
[3]=world
[03]=zeroworld
)
For compatibility with ksh93 / bash.
You would define it as an associative array (keys being arbitrary sequences of bytes, not numbers, though you're free to interpret as numbers if you wish), and
$ print -r -- $#test $test[3] $test[03]
4 world zeroworld
If you wanted to count the number of elements of a plain array that are not the empty string, you could do:
$ typeset -a test=()
$ test[1]=hello test[7]=foo test[3]=world
$ (){print $#} $test
3
Here relying on the fact that unquoted parameter expansions elide empty elements (to help compatibility with ksh).
Compare with:
$ (){print $#} "$test[@]"
7
(reminiscent of the Bourne shell's "$@"
) which doesn't elide them.
You could elide them explicitly as well with the ${array:#pattern}
operator which removes elements that match a pattern:
$ (){print $#} "${test[@]:#}"
3
Note that ${#array[@]}
is the Korn shell syntax. In zsh
, you can use $#array
like in csh (though it also supports the Korn syntax).
typeset -A test
to set the type to associative array.