Как мне объединить хеш в Perl? - PullRequest
3 голосов
/ 11 апреля 2011

У меня есть массив ссылок на хэш. Хэши содержат 2 ключа, USER и PAGES. Цель здесь состоит в том, чтобы просмотреть массив ссылок на хэш и сохранить итоговое количество страниц, напечатанных пользователем на принтере (это происходит из журналов событий). Я извлек данные из электронной таблицы Excel и использовал регулярные выражения для извлечения имени пользователя и страниц. В электронной таблице 182 строки, и каждая строка содержит имя пользователя и количество страниц, которые они напечатали в этом задании. В настоящее время сценарий может печатать каждое задание на печать (все 182) с именем пользователя и страницами, которые они напечатали, но я хочу объединить это так, чтобы оно показывало: имя пользователя 266 (то есть просто покажет имя пользователя один раз и общее количество напечатанных страниц для всей таблицы.

Вот моя попытка просмотреть массив ссылок на хеш, посмотреть, существует ли пользователь уже и, если да, + = количество страниц для этого пользователя в новом массиве ссылок на хеш (меньший). Если нет, то добавьте пользователя в новый массив хеш-ссылок:

my $criteria = "USER";
my @sorted_users = sort { $a->{$criteria} cmp $b->{$criteria} } @user_array_of_hash_refs;

my @hash_ref_arr;
my $hash_ref = \@hash_ref_arr;

foreach my $index (@sorted_users)
{
    my %hash = (USER=>"",PAGES=>"");
    if(exists $index{$index->{USER}})
    {
        $hash{PAGES}+=$index->{PAGES};
    }
    else
    {
        $hash{USER}=$index->{USER};
        $hash{PAGES}=$index->{PAGES};
    }
    push(@hash_ref_arr,{%hash});
}

Но выдает ошибку:

Для глобального символа "% index" требуется явное имя пакета в ...

Может быть, моя логика не самая лучшая в этом. Я должен использовать массивы вместо этого? Кажется, что хеш - лучшая вещь здесь, учитывая природу моих данных. Я просто не знаю, как сузить массив ссылок на хэш, чтобы просто получить имя пользователя и общее количество напечатанных страниц (я знаю, что мне кажется избыточным, но я просто пытаюсь быть понятным). Спасибо.

Ответы [ 4 ]

3 голосов
/ 11 апреля 2011
my %totals;

$totals{$_->{USER}} += $_->{PAGES} for @user_array_of_hash_refs;

А затем, чтобы получить данные:

print "$_ : $totals{$_}\n" for keys %totals;

Вы также можете отсортировать по использованию:

print "$_ : $totals{$_}\n" for sort { $totals{$a} <=> $totals{$b} } keys %totals;
2 голосов
/ 11 апреля 2011

Как уже упоминалось в mkb, ошибка находится в следующей строке:

if(exists $index{$index->{USER}})

Однако после чтения вашего кода ваша логика неисправна.Простое исправление синтаксической ошибки не даст желаемых результатов.

Я бы рекомендовал пропустить использование временного хэша в цикле.Просто работайте с хешем результатов напрямую.

Например:

#!/usr/bin/perl
use strict;
use warnings;

my @test_data = (
    { USER => "tom", PAGES => "5" },
    { USER => "mary", PAGES => "2" },
    { USER => "jane", PAGES => "3" },
    { USER => "tom", PAGES => "3" }
);

my $criteria = "USER";
my @sorted_users = sort { $a->{$criteria} cmp $b->{$criteria} } @test_data;

my %totals;

for my $index (@sorted_users) {
    if (not exists $totals{$index->{USER}}) {
        # initialize total for this user
        $totals{$index->{USER}} = 0;
    }

    # add to user's running total
    $totals{$index->{USER}} += $index->{PAGES}
}

print "$_: $totals{$_}\n" for keys %totals;

Это дает следующий вывод:

$ ./test.pl
jane: 3
tom: 8
mary: 2
0 голосов
/ 11 апреля 2011
my %total;
for my $name_pages_pair (@sorted_users) {
  $total{$name_pages_pair->{USER}} += $name_pages_pair->{PAGES};
}

for my $username (sort keys %total) {
  printf "%20s %6u\n", $username, $total{$username};
}
0 голосов
/ 11 апреля 2011

Ошибка исходит из этой строки:

if(exists $index{$index->{USER}})

Символ $ в Perl 5 с {} после имени означает, что вы получаете скалярное значение из хэша. Нет хэша, объявленного именем %index. Я думаю, что вам, вероятно, просто нужно добавить оператор ->, поэтому проблемная строка становится такой:

if(exists $index->{$index->{USER}})

но отсутствие данных делает меня неуверенным.

Также, хорошо, что вы используете use strict, иначе вы бы молча создали экземпляр %index и задались вопросом, почему ваши результаты не имеют никакого смысла.

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