我是Perl的新手,需要快速完成任务。任何帮助表示赞赏!
我有两个数组哈希如下:
Hash 1
-------
w: ['A','B','C']
e: ['P','Q','R']
Hash 2
-------
w:['A','B','C']
e:['P','Q','O']
r:['S','T']
背景:
我想找到相同键值的差异(例如Hash 1没有 来自Hash 2的值'O'表示相同的密钥'e'。
找出键的差异。 (例如'r'不存在于散列1中。
我把一些代码放在一起,但它从两个哈希中检查完整行的确切值。例如,如果我标记了差异,那么对于密钥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
}
}
答案 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;
}