2009-08-13 32 views
10

如何在不使用Data :: Compare的情況下比較Perl中的兩個哈希值?如何在不使用Data :: Compare的情況下比較Perl中的兩個哈希值?

+12

那麼,你看看Data :: Compare,看看他們做了什麼。你爲什麼不想使用該模塊? – 2009-08-13 20:50:04

+0

的可能的複製[Perl的 - 比較兩個嵌套的散列(https://stackoverflow.com/questions/37135504/perl-compare-two-nested-hash) – 2017-11-24 09:40:17

回答

20

最佳方法因您的目的而異。思南提到的FAQ項目是一個很好的資源:How do I test whether two arrays or hashes are equal?。在開發和調試過程中(當然在編寫單元測試時),我發現Test::More在比較數組,哈希和複雜數據結構時很有用。一個簡單的例子:

use strict; 
use warnings; 

my %some_data = (
    a => [1, 2, 'x'], 
    b => { foo => 'bar', biz => 'buz' }, 
    j => '867-5309', 
); 

my %other_data = (
    a => [1, 2, 'x'], 
    b => { foo => 'bar', biz => 'buz' }, 
    j => '867-5309x', 
); 

use Test::More tests => 1; 
is_deeply(\%other_data, \%some_data, 'data structures should be the same'); 

輸出:

1..1 
not ok 1 - data structures should be the same 
# Failed test 'data structures should be the same' 
# at _x.pl line 19. 
#  Structures begin differing at: 
#   $got->{j} = '867-5309x' 
#  $expected->{j} = '867-5309' 
# Looks like you failed 1 test of 1. 
+2

它看起來像Test :: Deep受到is_deeply的啓發。我的問題是,如何使cmp_deeply成爲測試的一部分而不是自行測試?因爲我的測試列表只有8個,但是每次我使用cmp_deeply時,它都會作爲一個測試,因此當我只有8個函數時,我的實際測試數量爲11(因爲我稱cmp_deeply爲3次)。我不想增加我的測試數量。有更可行的解決方案嗎? – biznez 2009-08-13 21:37:53

+0

@yskhoo。每次你調用其中一個測試函數('ok','cmp_deeply'等)時,它就算是一個測試。據我所知,沒有辦法避免這種情況。如果您不想事先提交特定數量的測試,則可以在加載測試模塊時執行此操作:'使用Test :: More qw(no_plan);'。 – FMc 2009-08-13 21:52:11

+5

您已經在http://stackoverflow.com/questions/1274756/how-can-i-use-perls-testdeepcmpdeeply-without-increasing-the-test-count中詢問了這個問題。你沒有回答爲什麼你不能增加測試的數量,或者你的數據結構如此複雜以至於你需要調用cmp_deeply三次。請回答你提出的問題,並確定真正的問題是什麼。如果您想提供更多信息,也許我們可以提供幫助。 – Ether 2009-08-14 16:46:01

3

How do I test whether two arrays or hashes are equal?

Perl的常見問題和答案,你的Perl發行版的一部分。您可以通過運行查看這個答案與您perl附帶的版本:

$ perldoc -q equal

在終端

+0

什麼是凍融cmpStr和cmpStrHard之間的區別? – biznez 2009-08-13 21:05:44

10

比較談論哈希值時,不是詳細的足夠的短語。有很多方法可以比較哈希值:

它們是否具有相同數量的密鑰?

if (%a == %b) { 
    print "they have the same number of keys\n"; 
} else { 
    print "they don't have the same number of keys\n"; 
} 

這兩個哈希鍵是否相同?

if (%a != %b) { 
    print "they don't have the same number of keys\n"; 
} else { 
    my %cmp = map { $_ => 1 } keys %a; 
    for my $key (keys %b) { 
     last unless exists $cmp{$key}; 
     delete $cmp{$key}; 
    } 
    if (%cmp) { 
     print "they don't have the same keys\n"; 
    } else { 
     print "they have the same keys\n"; 
    } 
} 

它們在兩個哈希中是否具有相同的鍵和相同的值?

if (%a != %b) { 
    print "they don't have the same number of keys\n"; 
} else { 
    my %cmp = map { $_ => 1 } keys %a; 
    for my $key (keys %b) { 
     last unless exists $cmp{$key}; 
     last unless $a{$key} eq $b{$key}; 
     delete $cmp{$key}; 
    } 
    if (%cmp) { 
     print "they don't have the same keys or values\n"; 
    } else { 
     print "they have the same keys or values\n"; 
    } 
} 

他們是同構的嗎(我將這個留給讀者,因爲我不是特別想從頭開始實現它)?

或其他一些相等的措施?

而且,當然,這段代碼只處理簡單的哈希值。添加複雜的數據結構使其更加複雜。

2

快速,骯髒,我敢肯定不是效率:

use strict; 
use warnings; 

use Data::Dumper; 

sub compare ($$) { 
    local $Data::Dumper::Terse = 1; 
    local $Data::Dumper::Indent = 0; 
    Dumper(shift) eq Dumper(shift); 
} 

my %a = (foo => 'bar', bar => [ 0 .. 3 ]); 
my %b = (foo => 'bar', bar => [ 0 .. 3 ]); 
my %c = (foo => 'bar', bar => [ 0 .. 4 ]); 

print Dumper compare \%a, \%b; 
print Dumper compare \%a, \%c; 
+1

這種方法加上['Text :: Diff'](https://metacpan.org/module/Text::Diff)會打印一個有用的報告。 – Lumi 2012-05-03 09:24:31

+2

此外,您應該執行'local $ Data :: Dumper :: Sortkeys = 1;'以確保鍵的順序相同。 – skaurus 2013-09-05 14:24:21

+0

@skaurus:爲什麼?他們不會是在相同的順序嗎? – zakovyrya 2013-09-05 15:35:38

-1

爲了比較:

sub HashCompare { 
    my ($a, $b) = @_; 
    my %rhash_1 = %$a; 
    my %rhash_2 = %$b; 

    my $key   = undef; 
    my $hash_2_line = undef; 
    my $hash_1_line = undef; 

    foreach $key (keys(%rhash_2)) { 
    if (exists($rhash_1{$key})) { 
    if ($rhash_1{$key} ne $rhash_2{$key}) { 
    print "key $key in $file_1 = $rhash_1{$key} & $rhash_2{$key} in $file_2\n"; 
     } 
     } 
    } 
    else { 
     print "key $key in $file_1 is not present in $file_2\n"; 

      #next; 
     } 
    } 

    foreach my $comp_key (keys %rhash_1) { 
     if (!exists($rhash_2{$comp_key})) { 
      print MYFILE "key $comp_key in $file_2 is not present in $file_1\n"; 
     } 
    } 
    return; 
} 

沒有重複鍵創建哈希:

sub CreateHash { 
    my (@key_val_file) = @_; 
    my $key_count  = 1; 
    my %hash_key_val =(); 
    my $str4   = undef; 

    local $/ = undef; 

    foreach my $each_line (@key_val_file) { 
      @key_val = split(/,/, $each_line); 
      if (exists($hash_key_val{$key_val[0]})) { 
        $key_count = $key_count + 1; 
        $str4  = $key_val[0] . " occurence-" . $key_count; 
        $hash_key_val{$str4} = $key_val[1]; 
       } 
       else { 
        $hash_key_val{$key_name} = $key_val[1]; 
       } 
      } 
     } 

     $key_count = 1; 

    close FILE; 

    return %hash_key_val; 
} 
+0

請爲您的答案提供解釋。 – 2012-10-26 09:25:10

+0

$ key_name從哪裏來? – nurp 2017-11-14 10:13:25

相關問題