最近在学习Perl相关的东西,这语言还是蛮强大的,用起来在很多方面也很方便的。和其他脚本语言很相似的是,不要花大块的时间来学习,可以在使用 过程中学习,这样才能发现真正不懂得地方,激发找出答案的欲望。OK,不闲谈了,接下来谈一下经常会用到的哈希在Perl中一些常见的额问题。
将数据填入哈希结构
$food{'apple'}='fruit';
$food{'pear'}='fruit';
$food{'carrot'}='vegetable';
print $food{'apple'};
输出:
fruit
若要使这个代码变得短一些,可以用一个列表对该哈希结构进行初始化。该列表应该包含成对的关键字与值,如下所示:
%food = ('apple','fruit','pear','fruit','carrot','vegetable');
print $food{'apple'};
输出:
fruit
Perl有一个特殊的运算符,称为逗号箭头运算符,即=>。使用=>运算符,同时利用Perl忽略白空间的特性,就能够编写下面这样的哈希结构的初始化代码:
%food = ('apple'=>'fruit','pear'=>'fruit','carrot'=>'vegetable');
print $food{'apple'};
输出:
fruit
=>运算符的左边将是个简单的字符串,不需要用引号括起来。另外,花括号中的单个单词的哈希关键字会自动加上引号。因此,前面显示的初始化代码将变成下面的形式:
%food = (apple=>'fruit',pear=>'fruit',carrot=>'vegetable');
print $food{apple};
输出:
fruit
从哈希结构中取出数据
若要从哈希结构中取出单个元素,只需要使用一个$、哈希结构的名字和你想要检索的关键字。请看下面这个例子:
%Movies = ( 'The Shining'=> 'Kubrick','Ten Commandments'=>'DeMille','Goonies'=>'Spielberg');
print $Movies{'The Shining'};
输出:
Kubrick
可以使用keys函数来检索作为列表返回的哈希结构的所有关键字,然后可以查看该列表,找出哈希结构的所有元素。在哈希结构的内部,它的关键字并不按照特定的顺序进行存放,keys函数返回的关键字也不使用特定的顺序。若要输出该哈希结构中的所有电影名字,可以使用下面的代码:
%Movies = ( 'The Shining'=> 'Kubrick','Ten Commandments'=>'DeMille','Goonies'=>'Spielberg');
foreach $film (keys %Movies){
}
输出:
Goonies
The Shining
Ten Commandments
%Movies = ( 'The Shining'=> 'Kubrick','Ten Commandments'=>'DeMille','Goonies'=>'Spielberg');
foreach $film (keys %Movies){
}
这个代码段输出的结果如下:
Goonies was directed by Spielberg
The Shining was directed by Kubrick
Ten Commandments was directed by DeMille
Perl还提供了另一个函数values,用于检索哈希结构中存放的所有值。如果仅仅检索值,通常是没有什么用处的,因为你不知道哪个关键字与哪个值相关联。返回的哈希结构的值的顺序与keys函数返回的关键字的顺序是相同的。现在请观察下面这个例子:
%Movies = ( 'The Shining'=> 'Kubrick','Ten Commandments'=>'DeMille','Goonies'=>'Spielberg');
@Directors = values %Movies;
@Films = keys %Movies;
print "@Directors";
print "\n";
print "@Films";
输出:
Spielberg Kubrick DeMille
Goonies The Shining Ten Commandments
有时,需要按值而不是按关键字从哈希结构中检索各个元素。按值来检索元素的最好方法是对哈希结构进行切换,也就是说,所有关键字变成值,所有值变成新哈希结构的关键字。那就使用reverse函数:
%Movies = ( 'The Shining'=> 'Kubrick','Ten Commandments'=>'DeMille','Goonies'=>'Spielberg');
%ByDirector = reverse %Movies;
@keys = keys %ByDirector;
@values = values %ByDirector;
print "@keys";
print "\n";
print "@values";
输出:
DeMille Spielberg Kubrick
Ten Commandments Goonies The Shining
请注意,现在所有的关键字值对的顺序都倒了过来(值放在了前面)。当你将这个列表赋予%ByDirector时,产生的哈希结构将与原始哈希结构相同,只不过现在所有的关键字变成了值,而所有的值则变成了关键字。不过你应该知道,如果由于某个原因你的哈希结构拥有相重复的值,如果该值(将要变成关键字)不是唯一的,那么你得到的哈希结构拥有的元素将比原先要少。由于在新的哈希结构中,重复的值会发生冲突,因此老的关键字将被新的关键字代替。
测试哈希结构中的关键字
%Movies = ( 'The Shining'=> 'Kubrick','Ten Commandments'=>'DeMille','Goonies'=>'Spielberg');
if(exists $Movies{'The Shining'}){
}
输出:
exists
从哈希结构中删除关键字
%Movies = ( 'The Shining'=> 'Kubrick','Ten Commandments'=>'DeMille','Goonies'=>'Spielberg');
if(delete $Movies{'The Shining'}){
}
输出:
exists
no exists
若要从哈希结构中删除所有关键字和值,只需要将哈希结构初始化为一个空的列表即可,如下所示:
%Hash = ();
在数组中寻找惟一的元素
@fishwords = ('one','fish','two','fish','red','fish','blue','fish');
%seen = ();
foreach(@fishwords){
}
@uniquewords = keys %seen;
@val = values %seen;
print "@uniquewords";
print "\n";
print "@val";
输出:
one
fish
two
fish
red
fish
blue
fish
blue one red two fish
1 1 1 1 1
给所有的%seen哈希数组赋值为1,由于关键字具有唯一性,所以%seen哈希数组只有五个关键字。
寻找两个数组之间的交汇部分
@stars = ('R.Reagan','C.Eastwood','M.Jackson','Cher','S.Bono');
@pols = ('N.Gingrich','S.Thurmon','R.Reagan','S.Bono','C.Eastwood','M.Thatcher');
%seen = ();
foreach(@stars){
}
@intersection = grep($seen{$_},@pols);
print "@intersection";
输出:
R.Reagan S.Bono C.Eastwood
寻找两个数组之间的不同部分
@stars = ('R.Reagan','C.Eastwood','M.Jackson','Cher','S.Bono');
@pols = ('N.Gingrich','S.Thurmon','R.Reagan','S.Bono','C.Eastwood','M.Thatcher');
%seen = ();
foreach(@stars){
}
@intersection = grep(!$seen{$_},@pols);
print "@intersection";
输出:
N.Gingrich S.Thurmon M.Thatcher
对哈希结构进行排序
%stars = ('R.Reagan','C.Eastwood','M.Jackson','Cher','S.Bono');
foreach( sort keys %stars){
}
输出:
M.Jackson Cher
R.Reagan C.Eastwood
S.Bono
%stars = ('R.Reagan','C.Eastwood','M.Jackson','Cher','S.Bono');
foreach( sort {$Stars{$a} <=> $stars{$b} }keys %stars){
}
输出:
R.Reagan C.Eastwood
S.Bono
M.Jackson Cher