2014-01-16 93 views
0

我有一組哈希值(使用Tie :: IxHash保留的密鑰序列),我想比較每個密鑰的值。散列的數量可能會有所不同。例如,我想要計算鍵「1」分配給值「1」和「0」的次數。我知道應該有一個很好的快速方法來計算值匹配,如果我把哈希值放入一個哈希數組中,然後循環遍歷它們,但是我卡住了,無法自行計算出來。在Perl中比較多個哈希值的密鑰值

%hash1 = (1 => '1', 
      2 => '1', 
      3 => '0', 
      4 => '0', 
     ); 

%hash2 = (1 => '1', 
      2 => '1', 
      3 => '1', 
      4 => '0', 
     ); 

%hash3 = (1 => '1', 
      2 => '1', 
      3 => '0', 
      4 => '1', 
     ); 

%hash4 = (1 => '1', 
      2 => '0', 
      3 => '0', 
      4 => '1', 
     ); 

對上述預期的結果是:

$key1: $agr1 = 4; $agr0 = 0; 
$key2: $agr1 = 3; $agr0 = 1; 
$key3: $agr1 = 1; $agr0 = 3; 
$key4: $agr1 = 2; $agr0 = 2; 

現在我終於實現了通過第一哈希鍵循環,隨後比較它們其他每個哈希,由於顯而易見的原因,這是乏味和愚蠢的。

感謝您的幫助!

更正:我使用散列,而不是散列參考。相應地編輯上面的代碼。

回答

2

這使得位的靈活性,你的結果,你可以把任何所需值@wanted。假設你的散列實際上是哈希引用(你的樣品中曖昧):

my @hashes = ($hash1,$hash2,$hash3,$hash4); 
my %count; 
for my $hash (@hashes) { 
    $count{ $_ }{ $hash->{$_} }++ for keys %$hash; 
} 
my @wanted = (1,0); 
for my $key (sort { $a <=> $b } keys %count) { 
    my @result = map { "agr$_ = " . ($count{$key}{$_} || 0) . ';' } @wanted; 
    print "key $key: @result\n"; 
} 

輸出:

key 1: agr1 = 4; agr0 = 0; 
key 2: agr1 = 3; agr0 = 1; 
key 3: agr1 = 1; agr0 = 3; 
key 4: agr1 = 2; agr0 = 2; 
+0

感謝,環做工精細。我也需要將協議值放入變量中,如我的問題所示,並將它們在鍵之間進行總結。你能指出如何在你的代碼中完成這項工作嗎? –

+0

您問題中的變量都具有相同的名稱$ agr0或$ agr1。你需要說'$ agr_1_k1_v0 = $ count {1} {0} || 0; $ agr_1_k1_v1 ...'爲每個你想要的鍵和值。所有你需要的信息都在%count哈希中,使用Data :: Dumper來打印它,你會看到。 – tangent

1

Pseudoperl:

# Build a list of refs to your hashes 
@a = { \%hash1, \%hash2, ... } 

# A container to hold the keys and counts 
$keys = {} 

# Initialize the key container 
for my $h in @a 
    for my $k in %$h 
     $keys->{$k} = {0 => 0, 1 => 0} unless exists $keys->{$k} 

# Iterate once over all the keys and count occurrences 
# assumes input hash values can be only 0 or 1 
for my $k in %$keys 
    for my $h in @a 
     $keys->{$k}->{$h->{$k}}++ if exists $h->{$k}; 
0

首先,你的哈希的例子是錯誤的。 %hash = {}

如果您使用%希望你想要()。如果你想要一個散列參考,它將是$hash = {}

回到你的問題。你可以做這樣的事情。

這通常被稱爲「看到」散列。

# appending your example above.... 
my @arr = (\%hash1, \%hash2, \%hash3, \%hash4); 
my $seen = {}; 

# iterate over each hash 
for my $hash (@arr) { 
    # iterate over each key in hash 
    for my $k (keys %$hash) { 
     my $val = $hash->{$k}; 

     # check $val and increment 
     if ($val) { 
      $seen->{$k}{1}++; 
     } else { 
      $seen->{$k}{0}++; 
     } 
    } 
} 

for my $k (sort keys %$seen) { 
    # in case any value is 0/undef 
    print "$k: 1 = " 
     . ($seen->{$k}->{0} ? $seen->{$k}->{0} : 0) . " 0 = " 
     . ($seen->{$k}->{0} ? $seen->{$k}->{0} : 0) . "\n"; 
} 

,輸出:

$ perl test.pl 
1: 1 = 0 0 = 0 
2: 1 = 1 0 = 1 
3: 1 = 3 0 = 3 
4: 1 = 2 0 = 2