Zsh 開發指南(第六篇 哈希表)

導讀

哈希表是比數組更復雜的數據結構,在某些語言裏被稱做關聯數組或者字典等等。簡單說,哈希表用於存放指定鍵(key)對應的值(value),鍵和值的關係,就像字典中單詞和釋義的對應關係,經過單詞能夠快速找到釋義,而不須要從頭依次遍歷匹配。準確地說,哈希表只是該功能的一種實現方式,也可使用各類樹或者其餘數據結構來實現,不一樣的實現方式適合不一樣的場景,使用方法是同樣的。但爲了簡化概念,統一使用哈希表這個名稱。git

哈希表定義

和其餘變量類型不一樣,哈希表是須要提早聲明的,由於哈希表的賦值語法和數組同樣,若是不聲明,是沒法區分的。github

% typeset -A hashmap
# 或者用 local,兩者功能是同樣的
% local -A hashmap

# 賦值的語法和數組同樣,但順序依次是鍵、值、鍵、值
% hashmap=(k1 v1 k2 v2)

# 直接用 echo 只能輸出值
% echo $hashmap
v1 v2

# 使用 (kv) 同時輸出鍵和值,(kv) 會把鍵和值都放到同一個數組裏
% echo ${(kv)hashmap}
k1 v1 k2 v2
 
# 哈希表的大小是鍵值對的數量
% echo $#hashmap
2

元素讀寫

讀寫哈希表的方法和數組相似,只是用於定位的數字變成了字符串。數組

# 能夠聲明和賦值寫到一行
% local -A hashmap=(k1 v1 k2 v2 k3 v3)
% echo $hashmap[k2]
v2

% hashmap[k2]="V2"

# 刪除元素的方法和數組不一樣,引號不能省略
% unset "hashmap[k1]"
% echo ${(kv)hashmap}
k2 V2 k3 v3

哈希表拼接

# 追加元素的方法和數組同樣
% hashmap+=(k4 v4 k5 v5)
% echo $hashmap
V2 v3 v4 v5


% local -A hashmap1 hashmap2
% hashmap1=(k1 v1 k2 v2)
% hashmap2=(k2 v222 k3 v3)

# 拼接哈希表,要展開成數組再追加
% hashmap1+=(${(kv)hashmap2})
# 若是鍵重複,會直接替換值,哈希表的鍵是不重複的
% echo ${(kv)hashmap1}
k1 v1 k2 v222 k3 v3

哈希表遍歷

用 (kv) (k) 等先將哈希錶轉化成數組,而後再遍歷。微信

% local -A hashmap=(k1 v1 k2 v2 k3 v3)

# 只遍歷值
% for i ($hashmap) {
> echo $i
> }
v1
v2
v3

# 只遍歷鍵
% for i (${(k)hashmap}) {
> echo $i
> }
k1
k2
k3

# 同時遍歷鍵和值
% for k v (${(kv)hashmap}) {
> echo "$k -> $v"
> }
k1 -> v1
k2 -> v2
k3 -> v3

元素查找

判斷鍵是否存在。數據結構

% local -A hashmap=(k1 v1 k2 v2 k3 v3)
% (($+hashmap[k1])) && echo good
good
% (($+hashmap[k4])) && echo good

若是須要判斷某個值是否存在,直接對值的數組判斷便可。但這樣作就體現不出哈希表的優點了。ide

% local -A hashmap=(k1 v1 k2 v2 k3 v3)
# value 不能也能是哈希表,也能夠用 local -a 強行聲明爲數組
% value=($hashmap)

% (( $value[(I)v1] )) && echo good
good
% (( $value[(I)v4] )) && echo good

元素排序

對哈希表元素排序的方法,和數組相似,多了 k v 兩個選項,其他的選項如 o(升序)、O(降序)、n(按數字大小)、i(忽略大小寫)等通用,再也不一一舉例。ui

% local -A hashmap=(aa 33 cc 11 bb 22)

# 只對值排序
% echo ${(o)hashmap}
11 22 33

# 只對鍵排序
% echo ${(ok)hashmap}
aa bb cc

# 鍵值放在一塊兒排序
% echo ${(okv)hashmap}
11 22 33 aa bb cc

從字符串、文件構造哈希表

由於哈希表能夠從數組構造,因此從字符串、文件構造哈希表,和數組的操做是同樣的,再也不一一舉例。code

% str="k1 v1 k2 v2 k3 v3"
% local -A hashmap=(${=str})
% echo $hashmap
v1 v2 v3

對哈希表中的每一個元素統一處理

對哈希表中的每一個元素統一處理,和對數組的操做是相似的,多了 k v 兩個選項用於指定是對鍵處理仍是對值處理,能夠一塊兒處理。再也不一一舉例。排序

% local -A hashmap=(k1 v1 k2 v2 k3 v3)
% print ${(U)hashmap}
V1 V2 V3

% print ${(Uk)hashmap}
K1 K2 K3

% print ${(Ukv)hashmap}
K1 V1 K2 V2 K3 V3

:# 也能夠在哈希表上用。ip

% local -A hashmap=(k1 v1 k2 v2 k3 v3)

# 排除匹配到的值
% echo ${hashmap:#v1}
v2 v3

# 只輸出匹配到的鍵
% echo ${(Mk)hashmap:#k[1-2]}
k1 k2

總結

本篇簡單講了哈希表的基本用法。篇幅不長,但由於哈希表的操做和數組相似,不少操做數組的方法均可以用做哈希表上,並且能夠把鍵或者值單獨做爲數組處理,因此操做哈希表更爲複雜一些。

另外還有一些更進階的處理數組和哈希表方法,以後會講到。

本文再也不更新,全系列文章在此更新維護:github.com/goreliu/zshguide

付費解決 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等領域相關問題,靈活訂價,歡迎諮詢,微信 ly50247。

相關文章
相關標籤/搜索