正如在另一篇关于数组的文章中看到的,我尝试了以下方法:
test[1]="hello"
test[7]="foo"
test[3]="world"
echo ${#test[@]}
7
但它给了我关联数组的最后一个索引。
如何获取关联数组的长度?
答案1
除非您事先运行过typeset -A test
,否则将分配普通数组的元素,而不是关联数组。
zsh 数组与大多数 shell 和语言的数组一样(我知道的唯一例外是 ksh(以及复制 ksh 数组设计的 bash))并不稀疏。
如果设置索引 1 和 7 的元素,而不将索引 2 的元素设置为 6,则仍然会分配一个包含 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 shell 的"$@"
),它不会删除它们。
您也可以使用删除与${array:#pattern}
模式匹配的元素的运算符显式删除它们:
$ (){print $#} "${test[@]:#}"
3
请注意,这${#array[@]}
是 Korn shell 语法。在 中zsh
,您可以像 csh 中一样使用$#array
(尽管它也支持 Korn 语法)。