0

我对 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. 我想找到相同键的值的差异(例如,对于相同的键'e',哈希 1 没有来自哈希 2 的值'O'。

  2. 找出键的不同。(例如,哈希 1 中不存在“r”。

我将一些代码放在一起,但它会从两个哈希中检查完整行的确切值。例如,如果我在哈希 1 中有 'A'、'B'、'C' 用于键 w 和 'B'、'C'、'A' 在哈希 2 中用于相同的键,如果标记差异。我想按价值比较价值-

以下代码比较了两个哈希 os 数组。因此,从上面的示例中,哈希 1 中的 A、B、C 不等于哈希 2 中的 B、A、C。但是我想检查单个项目的存在,比如 A,而不用担心顺序。

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

2 回答 2

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
        ...
    }
}
于 2012-07-30T16:58:20.293 回答
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;
}
于 2012-07-30T17:06:35.730 回答