在Perl中按值比较两个数组的哈希值

时间:2012-07-30 16:40:07

标签: perl

我是Perl的新手,需要快速完成任务。任何帮助表示赞赏!

我有两个数组哈希如下:

Hash 1
-------
w: ['A','B','C']
e: ['P','Q','R']

Hash 2
-------
w:['A','B','C']
e:['P','Q','O']
r:['S','T']

背景:

  1. 我想找到相同键值的差异(例如Hash 1没有    来自Hash 2的值'O'表示相同的密钥'e'。

  2. 找出键的差异。 (例如'r'不存在于散列1中。

  3. 我把一些代码放在一起,但它从两个哈希中检查完整行的确切值。例如,如果我标记了差异,那么对于密钥w,哈希1中的'A','B','C'和密钥w中的'B','C','A'在哈希2中用于相同的密钥。我想比较价值 -

    以下代码比较两个哈希os数组。所以从上面的例子A,B,来自散列1的C不等于散列2中的B,A,C。但是我想检查单个项目是否存在,而不是担心顺序。

    for ( keys %hash2 ) 
    {     
        unless ( exists $hash1{$_} ) # Checks for mismatches in keys
        {         
            print "$_: Key mismatch $_ received \n"; 
            next;     
        }      
    
        if ( $hash2{$_} eq $hash1{$_} ) #Compares two lines exactly         
        {        
            print "$_: No mismatch \n";  
        }     
        else 
        {       
            print "$_: Value mismatch for key $_ \n";  #Difference in Value
        } 
    } 
    

2 个答案:

答案 0 :(得分:0)

如果您不关心订单,只需比较有序的值集:

您的代码:

if ( $hash2{$_} eq $hash1{$_} ) #Compares two lines exactly      

应该是:

if (     join(",", sort @{ $hash1{$_}})
      eq join(",", sort @{ $hash2{$_}}) ) #Compares two lines exactly      

另一方面,如果要比较数组的成员资格,只需将数组转换为hashref:

foreach my $key2 ( keys %hash2 ) {
    unless ( exists $hash1{$key2} ) { print ""; next; };

    my %subhash1 = map { ( $_ => 1 ) } @{ $hash1{$key} };
    my %subhash2 = map { ( $_ => 1 ) } @{ $hash2{$key} };

    # Compare 2 subhashes same way you are comparing parent hashes in inner loop

    foreach my $subkey2 ( keys %subhash2 ) {
        # Check for exists
        ...
    }
}

答案 1 :(得分:0)

如果不重复数组的成员,则可以使用完全相同的算法来查找散列键的差异。因此,您可以将其设为子例程:

#!/usr/bin/perl
use warnings;
use strict;

my %h1 = (
          w => ['A','B','C'],
          e => ['P','Q','R'],
          q => [],
         );
my %h2 = (
          w => ['A','B','C'],
          e => ['P','Q','O'],
          r => ['S','T'],
         );


my @diff = list_diff(keys %h1, keys %h2);
print "Difference in keys: ", @diff, "\n" if @diff;

KEY:
foreach my $key (keys %h1) {
    next KEY unless exists $h2{$key};
    my @diff = list_diff(@{ $h1{$key} },@{ $h2{$key} });
    print "Difference at key $key: ", @diff, "\n" if @diff;
}


sub list_diff {
    my %keys;
    $keys{$_}++ for @_;
    return grep 2 != $keys{$_}, keys %keys;
}