1. 哈希
思考hash 的方法是,把它看作一堆数据(a barrel of data)(参见图6-2),每一个数据都有一个相应的标签。可以通过标签访问此标签对应的元素。但其中是没有“第一个”元素的概念的。在数组中,数组元素从0,1,2 开始编号。但在hash中,没有确定的顺序,因此也没有第一个元素。只是一些key/value 对的集合。
keys 和values 均为任意的标量,但keys 通常转换为字符串。因此,如果将表达式50/20 作为keys◆,则其通常被转换为3字符的字符串“2.5”。这是上图中的一个key。
1.1 为什么使用Hash?
1.2 哈希元素的存取
$hash{$some_key}
$family_name{“fred”} = “flintstone”;
$family_name{“barney”} = “rubble”
Hash 的key 可以是任意的表达式:
$foo = “bar”
print $family_name{$foo . “ney”}; #输出“rubble”
当将某个值存储在已经存在的hash 元素中,以前的值会被覆盖
$family_name{“wilma”} = “flintstone”; #新增或者替换已有的hash对,一个key(也包括value)
$family_name{“betty”} .= $family_name{“barney”}; #创建一个新元素,如果原来有则追加后赋值,如果没有则直接创建
访问不存在的hash 元素得到undef
1.2.1. 作为整体的hash
%family_name
%some_hash = (“foo”, 35, “bar”, 12.4, 2.5, “hello”, “wilma”, 1.72e30, “betty”, “bye/n”);#个数需偶,否则会警告
@array_array = %some_hash;# 我们把这称为:将hash 展开,并将其key/value 对返回到一个列表中。返回的key/value对顺序和存放的顺序可能不同
1.2.2.Hash 赋值
%new_hash = %old_hash;#不常用,因为效率较低
%inverse_hash = reverse %any_hash;#反转hash,值和key对调,但是最好你能确定原值是唯一的,否则系统采用覆盖的方式赋值,而hash又无序,所以你根本不知道到底谁覆盖了谁。
1.2.3.大箭头符号(=>)
my %last_name = (
“fred” => “flintstone”,
“dino” => undef,
“barney”=> “rubble”;
“betty”=> “rubble”,
);
1.3 哈希函数
1.3.1.keys 和values 函数
keys 函数会返回此hash 的所有keys,values 函数将返回所有的values
my %hash = (“a”=>1, “b”=>2, “c”=>3);
my @k = keys %hash;
my @v = values %hash;
此时他们的顺序用户是不能控制的,一旦再有对添加,顺序就会改变,但是如果a是第一个,那么1就也是第一个
my $count = keys %hash; #得到3,是指有3 个key/value 对,因为此时的上下文是数字标量
1.3.2.each 函数
while (($key, $value) = each %hash){
print “$key => $value/n”;
}
还可以对返回的key数组进行排序
foreach $key (sort keys %hash){
$value =$hass{$key};
print “$key => $value/n”;
#也可以不使用额外的临时变量$value
#print “$key => $hash{key}/n”;
}
1.4 哈希的通常用法
$books{“fred”} = 3;
$books{“wilma”} = 1;
很容易知道hash 的某个元素是true 还是false,像下面这样:
if($books{$someone}){
print “$someone has at least one book checked out./n”;
}
1.4.1.exists 函数(上面是判断有没有值,现在是判断有没有key)
if(exists $books{$dino}){
print “Hey, there’s a libaray card for dino!/n”;
}
1.4.2.delete 函数
delete 函数将某个给定的key(包括其对应的value)从hash 中删除。
my $person = “betty”;
delete $books{$person}; #将$person 的借书卡删除掉
1.4.3.hash 元素的内插
foreach $person (sort keys %books){
if($books{$person}){
print “$person has $books{$person} items/n” #fred 有3个
}
}
但不支持整个hash 的内插;“%books”仅是六个不同的字符%books