Perl 创建哈希字符串=>;列表列表,我做错了什么?

Perl 创建哈希字符串=>;列表列表,我做错了什么?,perl,Perl,在perl中,我试图建立一个列表列表的散列。它看起来像这样: my %entries; while(<>) { if(/complicated regex ommitted/) { my @entry = ($2, $3, $4); if(exists $entries{$1}) { push @{$entries{$1}}, @entry; } else

在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;
        }
}

您正在推送列表,而不是listref。尝试:

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

(你不需要先检查字段是否存在。如果它不存在,当你通过自动激活的神奇功能推到它时,它将被创建。)

你需要将引用推到列表上,否则列表只会被追加,这样你就可以得到一个简单的列表(请参阅上的手册)。“列表列表”在Perl中始终是一个“列表引用列表列表”。

Perl有一个名为autovivification的功能,可以在需要时使脚手架变得栩栩如生。这使您的代码保持简单:

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

呃,在
else
案例中,这不应该是
(\@entry)
?我尝试更改为listrefs(包括将else设置为一个明确的列表),但仍然得到相同的结果。我怀疑我迭代元素的代码可能有问题?@Svante:我已经更新了我的答案,以利用自动生存。谢谢!不过,关于输出的一个问题是,不是打印出单个条目的元素,而是打印出数组(0xaddress)。知道为什么吗?@tjm2001查看我的最新答案。我忽略了值是列表列表的部分,并希望它们是平面列表
使用严格将帮助您发现错误,
使用严格的;即使在不操作复杂数据结构的情况下,也强烈建议使用警告。
my %entries;
while(<>)
{
    if (/complicated regex ommitted/)
    {
        my($key,@entry) = ($1, $2, $3, $4);
        push @{ $entries{$key} }, \@entry;
    }
}
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";
    }
}
while ( <> ) {

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

print Dumper \%entry;