kf11859 发表于 2009-6-22 11:00:19

perl中的哈希表问题讨论



perl中的哈希表又被称为相关数组,是存储在内存中的一种有效的根据字段取值的列表,作用同xml文件有些类似。
举一个例子:
my%list=(“aa”=>”123”,”bb”=>”456”,”cc”=>”789”,”dd”=>”987”);
该语句定义了一个相关数组list,该数组的结构为:
字段名取值
aa            123
bb            456
cc            789
dd            987
可以看出该数组具有一个特性,就是每个元素并非像普通数组那样具有下标,取而代之的是一个字段名。这是一个很好用的特性,因为有时我们需要读取xml文件中的各字段,并将各字段的取值保存在内存中,这样可以有效避免每次要用到xml文件的时候都得从硬盘上读取所产生的资源消耗。
但是在下认为,该数组的优点和缺点是一对矛盾体,即优点与缺点并存,且相互关联。相关数组具有如下两个缺点是我们不得不去解决的:
1、相关数组的每个元素是无序的
2、相关数组的元素可以被覆盖
首先,相关数组的元素因为具有字段名和取值这两个值,在相关数组在被存储的时候是处于一种无序的状态,也就是说,计算机存储相关数组时,不会根据用户赋值的顺序来存储,这点可以参考如下例子验证:
#!/usr/bin/perl
use strict;
my %ss;
$ss{"aa"}="asasss";
$ss{"bb"}="rtytry";
$ss{"cc"}="iuiuyi";
$ss{"dd"}="rtytry";
my $key;
my $value;
while(($key,$value)=each %ss){
      print "$key : $value\n";
}
运行结果为:
cc : iuiuyi
bb : rtytry
dd : rtytry
aa : asasss
       从语句的先后顺序来看,在下是先赋值给aa,然后赋值给bb。。。这样一来的顺序,我希望的顺序是aa->bb->cc->dd,但运行结果并非希望的那样。
       为解决这个问题,目前我只能为该哈希表做一个索引数组来指导访问哈希表的各项字段。代码如下:
#!/usr/bin/perl
use strict;
my %ss;
$ss{"aa"}="asasss";
$ss{"bb"}="rtytry";
$ss{"cc"}="iuiuyi";
$ss{"dd"}="rtytry";
my @newlist=qw(aa bb cc dd);
for(my $i=0;$i<=$#newlist;$i++){
    my $value=$ss{$newlist[$i]};
    print "$newlist[$i] : $value\n";
}
运行结果为:
aa : asasss
bb : rtytry
cc : iuiuyi
dd : rtytry
       这是一种以牺牲资源为代价来获取的顺序的方法,在下试过用sort方法能够解决简单的根据字母顺序来获取字段名,但这种方法过于机械,不像上述例子那样灵活,无法应对复杂的字段排序,如果大家能够有更好的建议,请不吝赐教!
       第二个问题,哈希表对于读取的文件中相同字段名的赋值是看成重新赋值的,这句话的意思是,如果上述例子中字段aa已经被赋为asasss后,我如果想再增加一个字段aa,其取值为sdsdsdf,由于字段名同是aa,所以我增加字段aa后,perl解释为为aa重新赋值,从而覆盖了前面的取值。这也是一个要命的问题,很多情况下,因为想要读取文件的数据,而数据中具有相同的字段名,这样被读入的时候,哈希表自觉地将相同的字段名的取值覆盖,其实我并不希望perl那样做。
    这个问题在下无法解决,只能在读取文件后,将字段名添加后缀来唯一存储该字段,这样做只能说是一个下下策,因为这既会增加循环的次数,增加开销,还会造成修改了原有文件字段后,我不得不为它复原的麻烦。如果哪位高人能够指点迷津,在下不胜感激!
    总结:perl仍然主要是一个过程化的语言,尤其是在使用它做自动化测试工具时,我并不奢望它的面向对象特性能够给我带来实质上的效果。做好自动化测试脚本在于测试人员的脚本精妙,以最简单的执行过程完成复杂的测试逻辑。
页: [1]
查看完整版本: perl中的哈希表问题讨论