Как сравнить два хэша в Perl без использования Data:: Compare?
Как сравнить два хэша в Perl, не используя Data:: Compare?
Ответ 1
Лучший подход отличается в зависимости от ваших целей. Часто задаваемый вопрос, упомянутый Sinan, является хорошим ресурсом: Как проверить, равны ли два массива или хеши?. Во время разработки и отладки (и, конечно, при написании модульных тестов) я нашел 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
Сравнение не является достаточно подробной фразой при разговоре о хешах. Существует множество способов сравнения хэшей:
Есть ли у них одинаковое количество ключей?
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";
}
}
Являются ли они изоморфными (я оставлю это до читателя, поскольку я не хочу особенно пытаться реализовать его с нуля)?
Или какая-либо другая мера равных?
И, конечно, этот код касается только простых хэшей. Добавление сложных структур данных делает его еще более сложным.
Ответ 3
См. Как проверить, равны ли два массива или хеши?
Вопросы и ответы Perl являются частью вашего дистрибутива Perl. Вы можете просмотреть версию этого ответа, который пришел с вашим perl
, запустив:
$ perldoc -q equal
в вашем терминале.
Ответ 4
Быстро, грязно, и я уверен, что это не эффективно:
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;
Ответ 5
Test::Deep::NoTest имеет одинаковую функциональность.
Ответ 6
@zakovyrya Посмотрите этот ответ: fooobar.com/questions/509152/... Распознавание ключей происходит из внутренней структуры данных.
Ответ 7
Для сравнения:
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;
}