哈希表是比数组更复杂的数据结构,在某些语言里被称做关联数组或者字典等等。简单说,哈希表用于存放指定键(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。