如何從數組數組中檢索項目?
您好 StackExchange 專業人士!
我正在為 macOS 開發一個 zsh 項目。我使用 typeset 創建了三個關聯數組來保存值,並使用第四個數組來引用各個數組。是否可以遍歷 arrCollection 以從每個成員數組中檢索鍵/值對?請注意,下面數組中的鍵與我的生產腳本不同——它們只是鍵索引,而不是您可能在關聯數組中找到的更具描述性的鍵。
我想我可以像這樣使用參數擴展:
for k in $(sort <<< "${(kvF)arrCollection}"); do echo "$arrCollection["${(kvF)k}"]" done
不過我說的不太對。任何人都可以幫忙嗎?預期的輸出將是由換行符分隔的所有三個數組中的所有項目的列表。
下面的完整腳本範例。用法:arrTest.sh showAll
#!/bin/zsh key=$1 typeset -A arrOne arrTwo arrThree typeset -A arrCollection #Plan is to use an array of arrays so that a for loop can be used later to loop #through each key/value pair looking for a value that matches some pattern in an if statement #(if statement not included here). In the showAll case, how can I use parameter expansion to print all #of the values in each array? The if statement will further constrict what is actually echoed based on its #value. arrOne[1]="First" arrOne[2]="Second" arrOne[3]="Third" arrOne[4]="Fourth" arrTwo[1]="Purple" arrTwo[2]="Orange" arrTwo[3]="Red" arrTwo[4]="Green" arrTwo[5]="Blue" arrThree[1]="First" arrThree[2]="Red" arrThree[3]="Planet" arrThree[4]="Sun" arrThree[5]="Moon" arrThree[6]="Star" #Array of arrays arrCollection[1]=arrOne arrCollection[2]=arrTwo arrCollection[3]=arrThree #Expect a parameter if [ -z "$key" ] then echo "Please enter a parameter" else case "$key" in showAll) for k in $(sort <<< "${(kvF)arrCollection}"); do #This is the part I am having trouble with echo "$arrCollection["${(kvF)k}"]" done exit 1 ;; *) echo "Something goes here" exit 1 ;; esac fi
當您的鍵是從一開始的連續十進制數字時,不確定為什麼要使用關聯數組而不是普通數組,但是如果我正確理解您想要的內容,您可以這樣做:
for key in "${(nok@)arrCollection}"; do print -r - "Assoc $key: $arrCollection[$key]" printf ' "%s" => "%s"\n' "${(@kvP)arrCollection[$key]}" done
您的樣本上應該給出如下內容:
Assoc 1: arrOne "3" => "Third" "4" => "Fourth" "1" => "First" "2" => "Second" Assoc 2: arrTwo "3" => "Red" "4" => "Green" "5" => "Blue" "1" => "Purple" "2" => "Orange" Assoc 3: arrThree "3" => "Planet" "4" => "Sun" "5" => "Moon" "6" => "Star" "1" => "First" "2" => "Red"
或者也可以按鍵對每個關聯的成員進行數字排序:
for key in "${(nok@)arrCollection}"; do print -r - "Assoc $key: $arrCollection[$key]" for assoc_key in "${(@knoP)arrCollection[$key]}"; do printf ' "%s" => "%s"\n' "$assoc_key" "${${(P)arrCollection[$key]}[$assoc_key]}" done done
這會給:
Assoc 1: arrOne "1" => "First" "2" => "Second" "3" => "Third" "4" => "Fourth" Assoc 2: arrTwo "1" => "Purple" "2" => "Orange" "3" => "Red" "4" => "Green" "5" => "Blue" Assoc 3: arrThree "1" => "First" "2" => "Red" "3" => "Planet" "4" => "Sun" "5" => "Moon" "6" => "Star"
上面的鍵使用
o
(順序)和n
(數字)參數擴展標誌進行排序。除了由十進制數字序列組成的部分之外,元素使用區域設置排序順序進行比較。十進制數字序列被解釋為十進制整數並進行數字比較。這類似於 GNU 實現對/選項
sort
所做的事情。-V``--version-sort
例如so
foo2-3
would come beforefoo10-3
和 beforefoo2-10
,但不能用於正十進制整數以外的數字(-2
也將出現 before-10
和2.3
before2.10
)。要使用其他任意標准進行排序,雖然在 zsh 中以內置方式進行排序有很複雜的方法,但
sort
如果您可以保證元素不包含 NL 或 NUL 字元並且不為空,則可能更容易使用。以 GNU 為例
sort
:for key in ${(0)"$(print -rNC1 -- ${(k)arrCollection} | sort -zg)"}
以數字方式循環非空鍵,但這次支持各種數字表示(包括 0x20、1e-1、無窮大、-20、0x3.fp5…)。
上面是使用 NUL 分隔的記錄來提供列表
sort
並拆分其輸出,因此假設鍵不包含 NUL 字元。要改用 NL/LF 字元,請刪除-N
,-z
並更改(0)
為(f)
.¹ 和 NUL 字元必須單獨處理,因為標準比較 API 會阻塞它。