简体   繁体   English

使用perl对哈希值的哈希值求和

[英]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具有三个基本的数据结构:

  • Scalars ( $foo ) 标量( $foo
  • Arrays ( @foo ) 数组( @foo
  • Hashes ( %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 . 它不包含量值,而是对其中包含三个键的另一个哈希的引用: klmhijlkm 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM