Perl – 打印哈希
转自:清纯自然
紫英:对于学过C之后再学Perl的人来说印象比较深刻的就是:Perl可以一次性把整个数组打印出来,而C就不行。
比如,对于一个数组(1,2,3,4,5),在C中只能这么办:
1 2 3 4 5 6 7 8 9 10 11 |
# include int main() { int array[5]={1,2,3,4,5},i; for (i=0; i<5; i++) { printf("%d ", array[i]); //每个数字后面打印一个空格 } printf("\n"); return 0; } |
麻烦且不说,这样子最大的问题是末尾还会多打印出一个额外的空格。相比之下Perl就稍微简单一些,可以一次性把数组全部打印出来,中间自动插入空格隔开:
1 2 |
my @array = (1,2,3,4,5); print "@array\n"; |
初学Perl的人肯定要学“哈希”这种数据结构。郁闷的是,哈希就不能一次性打印出来了,只能像C那样用for循环逐个遍历打印:
1 2 3 4 5 6 7 8 9 10 |
my %ascii_for_char = ( '0' => 48, 'A' => 65, 'a' => 97, ); # 建立一个字符与ascii码的对应关系表 # 打印这个哈希 for $char ( keys %ascii_for_char ) { print("$char => $ascii_for_char{$char}\n"); } |
如果你想偷懒一点,要找一个能够一次性把整个哈希打印出来的特殊方法(最好是一个诸如print_hash()的函数,只要把哈希的名称给他,就能把整个哈希漂亮地打印出来),还真有这么个方法:使用Data::Dumper模块中的Dumper函数:
1 2 3 4 5 6 7 8 |
use Data::Dumper; my %ascii_for_char = ( '0' => 48, 'A' => 65, 'a' => 97, ); # 建立一个字符与ascii码的对应关系表 # 打印这个哈希 print Dumper(\%ascii_for_char); |
简单多了,结果会是这样:
1 2 3 4 5 |
$VAR1 = { 'A' => 65, 'a' => 97, '0' => 48 }; |
你可能会说:不稀奇!我可以自己写个打印哈希的子程序(或者叫做自定义函数):
1 2 3 4 5 6 7 8 9 |
# 用来打印哈希的子程序 sub print_hash { my $hash_ref = shift; for $key ( keys %{$hash_ref} ) { print("$key => $hash_ref->{$key}\n"); } } |
然后用它来打印上面那个哈希:
1 |
print_hash(\%ascii_for_char); |
不也很方便吗?
其实不是的。如果要打印的哈希里面还嵌套了其它的哈希或者数组,这时你的子程序就无能为例了,比如说:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
my %ascii_for_char = ( 'digit' => { '0' => 48, '1' => 49, }, 'upper case' => { 'A' => 65, 'B' => 66, }, 'lower case' => { 'a' => 97, 'b' => 98, }, ); |
这下子如果使用
1 |
print_hash(\%ascii_for_char); |
就得到这样的结果:
1 2 3 |
upper case => HASH(0x972b980) digit => HASH(0x970b818) lower case => HASH(0x972bc40) |
这显然是不行的。而使用Dumper函数就没关系了:
1 |
print Dumper(\%ascii_for_char); |
得到的是一个完整的嵌套哈希表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$VAR1 = { 'upper case' => { 'A' => 65, 'B' => 66 }, 'digit' => { '1' => 49, '0' => 48 }, 'lower case' => { 'A' => 98, 'a' => 97 } }; |
所以,Data::Dumper这个模块在调试复杂数据结构时相当有用!