2010-06-28 16 views
3

在perl中,我试图建立一个列表清单的散列。它看起来是这样的:创建哈希字符串=>列表列表,我做错了什么?

my %entries; 
while(<>) 
{ 
    if(/complicated regex ommitted/) 
    { 
     my @entry = ($2, $3, $4); 
     if(exists $entries{$1}) 
     { 
      push @{$entries{$1}}, @entry; 
     } 
     else 
     { 
      $entries{$1} = @entry; 
     } 
} 

所生成的散列了所有我所期望的按键,但价值“的名单列表”没有被正确地建立起来。我究竟做错了什么?

编辑:也许有什么毛病我怎么试图访问结果散列。这里是代码

foreach $key (keys %entries) 
{ 
    my $size = {@entries{$key}}; 
    # just says "HASH(0xaddress)"? 
    print "$key: $size\n"; 
    foreach(@{entries{$key}}) 
    { 
     # loop just goes through once, prints out just " : " 
     print "\t$_[0]: $_[1] $_[2]\n"; 
    } 
} 
+3

操纵当复杂的数据结构与Perl,增加'使用警告;'和'严格使用''在代码的顶部附近可以帮助你发现错误。 – 2010-06-28 18:46:13

+2

...和'严格使用;即使你不操作复杂的数据结构,强烈推荐使用警告。 – 2010-06-29 08:31:02

回答

4

Perl有一个称为autovivification的功能,可以在需要时使脚手架呈现春天生活。这使您的代码变得简单:

my %entries; 
while(<>) 
{ 
    if (/complicated regex ommitted/) 
    { 
     my($key,@entry) = ($1, $2, $3, $4); 
     push @{ $entries{$key} }, \@entry; 
    } 
} 

没有必要检查这是否是给定键的第一组条目。

转储的%entries内容,使用类似于

foreach my $key (sort keys %entries) 
{ 
    my $n = @{ $entries{$key} }; 
    print "$key ($n):\n"; 

    foreach my $l (@{ $entries{$key} }) 
    { 
     print "\t$l->[0]: $l->[1] $l->[2]\n"; 
    } 
} 
+0

谢谢!关于输出的一个问题是,不是打印出单个条目的元素,而是打印出ARRAY(0xaddress)。任何想法为什么? – tjm2001 2010-06-28 18:45:36

+0

@ tjm2001看到我更新的答案。我错过了列表中的值列表,并期望它们是扁平列表。 – 2010-06-28 18:48:57

4

你推一个列表,而不是一个listref。尝试:

push @{$entries{$1}}, \@entry; 

(你并不需要首先检查该字段的存在..如果它不存在,它会在你推到它,通过autovivication的奇迹产生。 )

+0

呃,在'else'情况下,不应该是'(\ @entry)'吗? – Svante 2010-06-28 18:24:28

+0

我试着改变listrefs(包括做其他的一个表达列表),但仍然得到相同的结果。我怀疑也许我的代码迭代元素是错误的呢? – tjm2001 2010-06-28 18:29:18

+0

@Svante:我已经更新了我的答案,以利用自动化。 – Ether 2010-06-28 18:36:35

0

您需要将参考推送到列表中,否则列表将被追加,以便获得一个简单列表(请参阅push上的手册)。 “列表列表”始终是Perl中的“列表引用列表”。

0
while (<>) { 

if (/ (r) (e) (g) (e) x /x) { 
    push @{ $entry{ $1 } }, [ $2, $3, $4 ]; 
} 
} 

或在1行代码:

/(r)(e)(g)(e)x/ and push @{$entry{$1}}, [$2, $3, $4] while <>; 

,并显示出它们:

use Data::Dumper; 

print Dumper \%entry; 
相关问题