哈希是使Perl 语言称为杰出编程语言的关键特色.哈希类似于Java 中的map 类型, 存储的是 key-value 键值对. perl 的哈希是非常高效的, 当hash 的元素有很多时, 查询也是相当快的.
1. 哈希特性
哈希结构存储的是一组 key-value 对的集合. 其中key 为字符串, value 为直接量, 可以通过key 来获取value 的值. 哈希和数组比较相似, 只不过数组是通过数字索引来获取元素的值, 哈希是通过字符串key来获取. 哈希结构的特性如下:
哈希是无序的哈希的key不能重复, 适合存储一对一, 多对一的关系哈希中可以存储无限多的key-value 对哈希拥有非常高效的算法以保证在哈希元素增多时, 查询速度依然很快哈希可以同时获取多个key的值哈希value还能是单个单数, 即为字符串, 数字, 不能为数组,列表或哈希.
2. 哈希基本操作
2.1 哈希创建
哈希变量命名: %+变量名, 如: %ip_hash创建哈希时, 在key的不产生歧义的情况下引号可用省略通常在创建哈希的时候, 会同时为哈希赋值, 有以下几种方式:
%hash_name= (key1
, value1
, key2
, value2
...);
%hash_name= (
key1
=> value1
,
key2
=> value2
,
...,
);
%hash_reverse = reverse
%hash_name;
$hash_name{key
} = value
;
%hash_name = ();
2.2 哈希引用
哈希元素也是单一的元素, 所以引用的时候也是使用$, 和数组不同的时, 后面跟{}而不是[]
哈希赋值语法格式
整体引用%hash_name单个元素引用$hash_name{key}
2.3 哈希元素提取
可以通过@符号提取哈希中的多个元素为数组, 或列表. 因为提取的为多个元素,所以用的是@而不是$.
哈希赋值语法格式
提取为数组@array=@hash_name{key1, key2 …};提取为列表($value1, $value2…) = @hash_name(key1, key2 …);
2.4 字符串内插
哈希整体本身不支持元素内插, 但是哈希元素支持遍历内插, 比如: “$hash_name{key}”哈希整体不支持字符串内插, 但是可以先将哈希转换为数组,然后使用数组内插,转换方式:@arrays=%hash_nane;
2.5 哈希上下文
perl 的数组是非常智能的, 能够揣摩你的代码上下文, 给你不同的返回结果.上下文是指,根据左侧变量类型,使用数组做不同的赋值.
哈希赋值示例描述
哈希上下文%hash1=%hash_name;等号左边为哈希变量,则表示哈希复制数组上下文@hashs=%hash_name;等号左边为数组,则表示转换哈希为数组
3. 哈希遍历
3.1 while-each 遍历
遍历结果是随机的, 因为hash 本身就是无序的
while(my ($key, $val) = each
%ips_hash){
print "$key --> $val \n";
}
3.2 keys 数组遍历
通过获取哈希的keys 列表进行遍历,可以进行有序遍历, 由于数组有很多遍历方式, 这样会衍生出很多遍历方式
foreach (keys
%ip_hash){
print "$_ --> $bookMap{$_}\n";
}
foreach (sort keys
%ip_hash){
print "$_ --> $bookMap{$_}\n";
}
3.3 keys-values 遍历
单独获取哈希的keys 和 values 是无序的 ,且不能保证以一对应连续获取哈希的keys 和 values 可以保证相同索引的key 和 value 是一一对应的.
@keys = keys
%hash_name;
@values = keys
%hash_name;
for my $idx ( 0..$#keys){
print "$keys[$idx] --> $values{$idx}\n";
}
3.4 哈希转换为数组遍历
创建哈希时可以由数组转换为哈希, 而数组支持字符串内插, 因此我们可以将哈希先转换为数组, 然后使用数组字符串内插来输出整个哈希
@hashs = %hash_name;
print "@hashs \n";
4. 综合示例
4.1 示例脚本
print "\n#################### 2.1 创建哈希 ####################i \n";
%char_hs = ( A
, 'a', B
, 'b', C
, 'c');
%ip_hs = (
"www.taobao.com" => "60.28.242.249",
"www.baidu.com" => "61.135.169.125",
);
%ip_reverse = reverse
%ip_hs;
$book_hash{"java"} = "Think in java ";
print "\n#################### 2.2 哈希引用 ####################\n";
%char_hs2 = %char_hs;
$char_A = $char_hs{A
};
print "char_A:$char_A \n";
print "\n#################### 2.3 哈希元素提取 ####################\n";
@char_array = @char_hs{A
, C
};
print "char_array: @char_array \n";
($char_B, $char_C) = @char_hs{A
, C
};
print "char_B: $char_B, char_C: $char_C \n";
print "\n#################### 2.4 哈希元素字符串内插 ####################\n";
print "char_A:$char_A, char_B: $char_B, char_C: $char_C \n";
print "\n#################### 3.1 while-each 遍历 ####################\n";
print "while-each 无序遍历 ip_hash: \n";
while (my ($key, $val) = each
%ip_hs) {
print "$key -> $val \n";
}
print "\n#################### 3.2 foreach 遍历 ####################\n";
print "foreach 有序遍历 char_hs: \n";
foreach (sort keys
%char_hs){
print "$_ -> $char_hs{$_} \n";
}
print "\n#################### 3.3 keys-values 遍历 ####################\n";
@keys = keys
%char_hs;
@values = values
%char_hs;
for my $idx (0..$#keys) {
print "$keys[$idx] -> $values[$idx] \n";
}
print "\n#################### 3.4 哈希转换为数组遍历 ####################\n";
@arrays = %ip_hs;
print "arrays: @arrays \n";
4.2 示例输出
#################### 2.1 创建哈希 ####################i
#################### 2.2 哈希引用 ####################
char_A:a
#################### 2.3 哈希元素提取 ####################
char_array: a c
char_B: a, char_C: c
#################### 2.4 哈希元素字符串内插 ####################
char_A:a, char_B: a, char_C: c
#################### 3.1 while-each 遍历 ####################
while-each 无序遍历 ip_hash:
www.taobao.com -> 60.28.242.249
www.baidu.com -> 61.135.169.125
#################### 3.2 foreach 遍历 ####################
foreach 有序遍历 char_hs:
A -> a
B -> b
C -> c
#################### 3.3 keys-values 遍历 ####################
B -> b
C -> c
A -> a
#################### 3.4 哈希转换为数组遍历 ####################
arrays: www.taobao.com 60.28.242.249 www.baidu.com 61.135.169.125