2007年4月29日星期日

《Learning Perl》学习笔记 -- 第五章 散列

本章讲述了散列(hash)的概念、访问方法及针对散列的一些函数

1.散列的概念

散列类似于数组,与数组相同的是它可以含有任意数目的值并随意读取它们;与数组不同的是,在散列中,使用的索引是字符串(这里成为键(key))而不是数值,即使用名字来查找对应的值。键是任意字符串,在某个确定的散列中,它的值是唯一的。

键和值(value)都是任意的标量,但键总是被转成字符串。

2.访问方法

和标量、数组一样,散列拥有独立的命名空间。

访问散列中的元素,可以使用如下的语法:

$hash{$some_key}

访问整个散列,使用百分号(%)做前缀

%hash

3.赋值

为了方便起见,可以将散列转换为一个列表,并转换回来。给散列赋值是一个列表上下文,这个表由键-值对组成:

%some_hash={"foo",35,"bar",12.4,2.5,"hello","wilma",1.72e30,"betty","byen");

在这种赋值中,不太容易分辨键和值的对应关系,在Perl中,可以使用大箭头(=>)来表示键和值的对应关系,如下所示:
%some_hash={
"foo" => 35,
"bar" => 12.4,
2.5 => "hello",
"wilma" => 1.72e30,
"betty" => "byen",
);
散列(在列表上下文中)的值是一个简单的键-值对列表:
@any_array = %some_hash;
上式称之为展开(unwind)散列,展开时不能预知键-值对的顺序,但是键和值总是对应的。

4.散列函数
4.1 keys和values函数
my @k = keys %hash; # 获得该散列中所有的键
my @v = values %hash; #获得该散列中所有的数值

在一个标量上下文中,这些函数给出散列中的元素(键-值对)个数
my $count = keys %hash;

4.2 each函数
each函数用于遍历一个散列,每次返回一个键-值对作为一个二元素列表。实际情况下,一般只在while循环中使用each,如下所示:
while ( ($key,$value) = each %hash) {
print "$key => $valuen";
}
上面这个例子用于遍历散列%hash,每次取一个键-值对,并将该键-值对赋给($key,$value)列表。当遍历完该散列时,($key,$value)=(undef,undef),此时,while循环条件不成立,则循环结束。

为了遍历散列,也可以使用foreach和keys函数相结合的方式,采用这种方式,还可以在遍历时对散列进行排序,如下所示:
foreach $key (sort keys %hash) {
...
}

4.3 exists函数
要查看某键是否在散列中,可以使用exists函数,它在键存在时返回真,不论相应的值是真还是假:
if (exists $books{"dino"}) {
...
}

4.4 delete函数
delete函数从散列中删去指定的键(和相应的值)。(如无此键,它的任务就结束了。此时既无警告,也没有错误消息。)
my $person = "betty";
delete $books{$person}; #撤销$person的借书卡

4.5 reverse操作符
使用reverse操作符可以生成一个逆散列,即原先的键变为新散列中的值,原先的值变成新散列中的键。如果原散列中的值不是唯一的(即值之间有重复),则无法判断新的散列中某个键对应的是哪个值。因此,使用reverse操作符变换散列一般只适用于键和值都是唯一(不重复)的散列。

没有评论: