[英]sum hash of hash values using perl
I have a Perl script that parses an Excel file and does the following : It counts for each value in column A, the number of elements it has in column B, the script looks like this : 我有一个Perl脚本,该脚本可以解析Excel文件并执行以下操作:它对A列中的每个值,B列中具有的元素数进行计数,该脚本如下所示:
use strict;
use warnings;
use Spreadsheet::XLSX;
use Data::Dumper;
use List::Util qw( sum );
my $col1 = 0;
my %hash;
my $excel = Spreadsheet::XLSX->new('inout_chartdata_ronald.xlsx');
my $sheet = ${ $excel->{Worksheet} }[0];
$sheet->{MaxRow} ||= $sheet->{MinRow};
my $count = 0;
# Iterate through each row
foreach my $row ( $sheet->{MinRow}+1 .. $sheet->{MaxRow} ) {
# The cell in column 1
my $cell = $sheet->{Cells}[$row][$col1];
if ($cell) {
# The adjacent cell in column 2
my $adjacentCell = $sheet->{Cells}[$row][ $col1 + 1 ];
# Use a hash of hashes
$hash{ $cell->{Val} }{ $adjacentCell->{Val} }++;
}
}
print "\n", Dumper \%hash;
The output looks like this : 输出看起来像这样:
$VAR1 = {
'13' => {
'klm' => 1,
'hij' => 2,
'lkm' => 4,
},
'12' => {
'abc' => 2,
'efg' => 2
}
};
This works great, my question is : How can I access the elements of this output $VAR1 in order to do : for value 13, klm + hij = 3 and get a final output like this : 这很好用,我的问题是:我该如何访问此输出$ VAR1的元素以进行操作:对于值13,klm + hij = 3,并得到如下最终输出:
$VAR1 = {
'13' => {
'somename' => 3,
'lkm' => 4,
},
'12' => {
'abc' => 2,
'efg' => 2
}
};
So basically what I want to do is loop through my final hash of hashes and access its specific elements based on a unique key and finally do their sum. 因此,基本上我想做的是遍历哈希的最终哈希,并根据唯一键访问其特定元素,最后求和。
Any help would be appreciated. 任何帮助,将不胜感激。 Thanks
谢谢
I used @do_sum
to indicate what changes you want to make. 我使用
@do_sum
指示您要进行哪些更改。 The new key is hardcoded in the script. 新密钥在脚本中进行了硬编码。 Note that the new key is not created if no key exists in the subhash (the
$found
flag). 请注意,如果子哈希中没有键(
$found
标志),则不会创建新键。
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
my %hash = (
'13' => {
'klm' => 1,
'hij' => 2,
'lkm' => 4,
},
'12' => {
'abc' => 2,
'efg' => 2
}
);
my @do_sum = qw(klm hij);
for my $num (keys %hash) {
my $found;
my $sum = 0;
for my $key (@do_sum) {
next unless exists $hash{$num}{$key};
$sum += $hash{$num}{$key};
delete $hash{$num}{$key};
$found = 1;
}
$hash{$num}{somename} = $sum if $found;
}
print Dumper \%hash;
It sounds like you need to learn about Perl References , and maybe Perl Objects which are just a nice way to deal with references. 听起来您需要了解Perl引用 ,也许还需要了解Perl对象 ,这只是处理引用的一种好方法。
As you know, Perl has three basic data-structures: 如您所知,Perl具有三个基本的数据结构:
$foo
) $foo
) @foo
) @foo
) %foo
) %foo
) The problem is that these data structures can only contain scalar data. 问题在于这些数据结构只能包含标量数据。 That is, each element in an array can hold a single value or each key in a hash can hold a single value.
也就是说,数组中的每个元素可以包含一个值,或者哈希中的每个键可以包含一个值。
In your case %hash
is a Hash where each entry in the hash references another hash. 在您的情况下,
%hash
是一个哈希,哈希中的每个条目都引用另一个哈希。 For example: 例如:
Your %hash
has an entry in it with a key of 13
. 您的
%hash
包含一个键为13
的条目。 This doesn't contain a scalar value, but a references to another hash with three keys in it: klm
, hij
, and lkm
. 它不包含标量值,而是对其中包含三个键的另一个哈希的引用:
klm
, hij
和lkm
。 YOu can reference this via this syntax: 您可以通过以下语法引用它:
${ hash{13} }{klm} = 1
${ hash{13} }{hij} = 2
${ hash{13} }{lkm} = 4
The curly braces may or may not be necessary. 可能不需要花括号。 However,
%{ hash{13} }
references that hash contained in $hash{13}
, so I can now reference the keys of that hash. 但是,
%{ hash{13} }
引用了$hash{13}
包含的$hash{13}
,因此我现在可以引用该哈希的键。 You can imagine this getting more complex as you talk about hashes of hashes of arrays of hashes of arrays. 您可以想象,当谈论数组数组的哈希值时,这种情况变得越来越复杂。 Fortunately, Perl includes an easier syntax:
幸运的是,Perl包含了一个更简单的语法:
$hash{13}->{klm} = 1
%hash{13}->{hij} = 2
%hash{13}->{lkm} = 4
Read up about hashes and how to manipulate them. 阅读有关散列以及如何操作它们的信息。 After you get comfortable with this, you can start working on learning about Object Oriented Perl which handles references in a safer manner.
对此感到满意之后,就可以开始学习有关面向对象的Perl的知识,它可以更安全地处理引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.