2012-11-15 3 views
0

Excel 파일을 구문 분석하고 다음을 수행하는 Perl 스크립트가 있습니다. A 열의 각 값, B 열의 요소 수를 계산합니다. 스크립트는 다음과 같습니다.perl을 사용하는 해시 값의 해시 합계

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 
       } 
    }; 

, 내 질문은 : 어떻게 수행하려면이 출력 $ VAR1의 요소에 액세스 할 수 있습니다 값 13, KLM + hij = 3이고 최종 출력은 다음과 같습니다.

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

그래서 기본적으로 해시의 마지막 해시를 반복하고 고유 키를 기반으로 특정 요소에 액세스 한 다음 마지막으로 합계를 계산합니다.

도움을 주시면 감사하겠습니다. 감사합니다.

+0

합계에 정확히 어떤 키를 사용 하시겠습니까? 모든 키? 지정된 키의 하위 집합? – Bitwise

+0

예이 합계는 모든 키에 영향을 미칩니다. 13은 klm + hij를 가지며 12는 klm + hij도 갖습니다. 내가 쓴 모범은 가난하다. 미안하다. 보다 현실적인 시나리오에서는 내가 가진 것 : $ VAR1 = { '13'=> { 'somename을'=> 3, 'LKM'=> 4, }, '12'=> { 'somename'=> 9, 'lkm'=> 6 } }}; – salamey

답변

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; 
+0

도움을 주셔서 감사합니다.하지만 해시의 모든 키에 대해이 작업을 수행하고 싶습니다. 루프가 필요할 것 같네요? (필자는 단지 Perl을 배우기 시작했습니다. 이해해 주셔서 감사합니다 :)) – salamey

+0

@ user1734229 : 업데이트를 확인하십시오. – choroba

+0

감사합니다. 매우 도움이되었습니다. 또 다른 질문으로,'@ do_sum'처럼 다른 키들과 합을주고 싶습니다.'@ do_sum2'에 "abc"와 "efg"를 넣고 싶습니다. 출력물은 'somename'과 같이 입력해야합니다 : 'somename'= > 10, 'othername'=> 12. @do_sum과'@ do_sum2'를 반복해야합니다. 어떻게 할 수 있습니까? – salamey

0

그것은 당신에 대한 Perl References을 배울 필요가 같은 소리, 참고 문헌을 다루는 단지 좋은 방법입니다 아마 Perl Objects.

  • 스칼라 ($foo)
  • 배열 (@foo)
  • 해시 (%foo)

문제가 있다는 것입니다 :

당신이 알고있는 바와 같이, 펄은 세 가지 기본 데이터 구조를 가지고 이러한 데이터 구조는 스칼라 데이터 만 포함 할 수 있습니다. 즉, 배열의 각 요소는 단일 값을 유지하거나 해시의 각 키는 단일 값을 보유 할 수 있습니다.

%hash은 해시로 각 해시 항목이 다른 해시를 참조하는 해시입니다. 예 :

%hash13 키가있는 항목이 있습니다. 여기에는 스칼라 값이 포함되지 않지만 그 안에 세 개의 키가있는 다른 해시 인 klm, hijlkm에 대한 참조가 포함되어 있습니다. 이 구문을 통해 이것을 참조 할 수 있습니다.

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

중괄호가 필요할 수도 있고 그렇지 않을 수도 있습니다. 그러나 %{ hash{13} }은 해당 해시가 $hash{13}에 포함되어 있음을 참조하므로 해시 키를 참조 할 수 있습니다. 배열 해시 배열의 해시 해시에 대해 이야기하면서 복잡 해짐을 상상할 수 있습니다.

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

해시 방법을 조작하는 방법에 대해 최대 읽기 : 다행히도, 펄은 쉽게 구문이 포함되어 있습니다. 이 작업에 익숙해지면 더 안전한 방식으로 참조를 처리하는 객체 지향 Perl에 대해 배우기 시작할 수 있습니다.