Zsh

zsh:如何獲得關聯數組長度?

  • May 11, 2022

正如在另一篇關於數組的文章中看到的那樣,我嘗試了這個:

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

但它給了我關聯數組的最後一個索引。

如何獲取關聯數組的長度?

除非您typeset -A test事先執行過,否則它將分配一個普通數組的元素,而不是關聯數組。

zsh 數組像大多數 shell 和語言的數組一樣(我知道的唯一例外是 ksh(和 bash 複製了 ksh 的數組設計))並不稀疏。

如果您設置索引 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’s "$@")這並沒有忽略它們。

${array:#pattern}您也可以使用刪除與模式匹配的元素的運算符顯式省略它們:

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

請注意,這${#array[@]}是 Korn shell 語法。在zsh, 你可以$#array在 csh 中使用 like (雖然它也支持 Korn 語法)。

引用自:https://unix.stackexchange.com/questions/702066