我有一个哈希引用数组。散列包含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”需要明确的包名称在...
也许我的逻辑不是最好的。我应该使用数组吗?考虑到我的数据的性质,似乎哈希是最好的事情。我只是不知道如何减少哈希引用数组,只是获取一个用户名和他们打印的总页数(我知道我似乎多余,但我只是想清楚)。谢谢。
答案 0 :(得分:3)
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;
答案 1 :(得分:2)
正如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
答案 2 :(得分:0)
错误来自这一行:
if(exists $index{$index->{USER}})
Perl 5中的$
sigil,名称后面带有{}
表示您从哈希中获取标量值。没有名称%index
声明的哈希。我认为您可能只需添加->
运算符,因此问题行变为:
if(exists $index->{$index->{USER}})
但没有数据让我不确定。
此外,您可以使用use strict
,或者您会默默地实例化%index
哈希,并想知道为什么您的结果没有任何意义。
答案 3 :(得分:0)
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};
}