0

Excelファイルを解析して次のことを行うPerlスクリプトがあります。列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;

出力は次のようになります。

$VAR1 = {
      '13' => {
                'klm' => 1,
                'hij' => 2,
                'lkm' => 4,
              },
      '12' => {
                'abc' => 2,
                'efg' => 2
              }
    };

これはうまく機能します。私の質問は次のとおりです。値13の場合、klm + hij = 3を実行し、次のような最終出力を取得するために、この出力$VAR1の要素にアクセスするにはどうすればよいですか。

$VAR1 = {
      '13' => {
                'somename' => 3,
                'lkm' => 4,
              },
      '12' => {
                'abc' => 2,
                'efg' => 2
              }
    };

つまり、基本的に私がやりたいのは、ハッシュの最後のハッシュをループし、一意のキーに基づいてその特定の要素にアクセスし、最後にそれらの合計を実行することです。

どんな助けでもいただければ幸いです。ありがとう

4

2 に答える 2

1

以前@do_sumは、どのような変更を加えたいかを示していました。新しいキーはスクリプトにハードコーディングされています。$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;
于 2012-11-15T13:21:38.437 に答える
0

Perl Referencesについて学ぶ必要があるように思えますが、おそらくPerl Objectsは、参照を処理するための優れた方法です。

ご存じのように、Perl には 3 つの基本的なデータ構造があります。

  • スカラー ( $foo)
  • 配列 ( @foo)
  • ハッシュ ( %foo)

問題は、これらのデータ構造にスカラーデータしか含めることができないことです。つまり、配列内の各要素が単一の値を保持したり、ハッシュ内の各キーが単一の値を保持したりできます。

あなたの場合%hash、ハッシュ内の各エントリが別のハッシュを参照するハッシュです。例えば:

のキー%hashを持つエントリがあり13ます。これにはスカラー値は含まれませんが、klmhij、の 3 つのキーを持つ別のハッシュへの参照が含まれますlkm。これは、次の構文で参照できます。

${ hash{13} }{klm} = 1
${ hash{13} }{hij} = 2
${ hash{13} }{lkm} = 4

中括弧は必要な場合とそうでない場合があります。ただし、 に%{ hash{13} }含まれるハッシュを参照する$hash{13}ので、そのハッシュのキーを参照できるようになりました。配列のハッシュの配列のハッシュのハッシュについて話すと、これがより複雑になることが想像できます。幸いなことに、Perl にはより簡単な構文が含まれています。

$hash{13}->{klm} = 1
%hash{13}->{hij} = 2
%hash{13}->{lkm} = 4

ハッシュとその操作方法について読んでください。これに慣れたら、より安全な方法で参照を処理するオブジェクト指向 Perl について学び始めることができます。

于 2012-11-15T14:58:50.357 に答える