Создание хэш-строки => списка списков, что я делаю не так? - PullRequest
3 голосов
/ 28 июня 2010

В 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";
    }
}   

Ответы [ 4 ]

4 голосов
/ 28 июня 2010

Perl имеет функцию, называемую автовивификацией, которая оживляет леса, когда вам это нужно.Это делает ваш код простым:

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";
    }
}
4 голосов
/ 28 июня 2010

Вы выдвигаете список, а не список ссылок. Попробуйте:

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

(Вам не нужно сначала проверять наличие поля ... если оно еще не существовало, оно будет создано, когда вы нажмете на него, через чудеса автовивации.)

0 голосов
/ 28 июня 2010
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;
0 голосов
/ 28 июня 2010

Вам нужно вставить ссылку в список, в противном случае списки просто добавляются, чтобы вы получили простой список (см. Руководство по push).«Список списков» - это всегда «список ссылок на списки» в Perl.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...