web-dev-qa-db-ja.com

Data :: Compareを使用せずにPerlで2つのハッシュを比較するにはどうすればよいですか?

Data :: Compareを使用せずにPerlで2つのハッシュを比較するにはどうすればよいですか?

13
biznez

最善のアプローチは、目的によって異なります。 FAQ Sinanが言及した項目は良いリソースです: 2つの配列またはハッシュが等しいかどうかをテストするにはどうすればよいですか? 。開発中およびデバッグ中(そしてもちろん書き込み中)ユニットテスト)私が見つけた 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.
22
FMc

ハッシュについて話すとき、比較は十分に詳細なフレーズではありません。ハッシュを比較する方法はたくさんあります。

それらは同じ数のキーを持っていますか?

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";
    }
}

それらは同形ですか(特に最初から実装しようとは思わないので、これは読者に任せます)?

または他の同等の尺度?

そしてもちろん、このコードは単純なハッシュのみを扱います。複雑なデータ構造を追加すると、さらに複雑になります。

10
Chas. Owens

2つの配列またはハッシュが等しいかどうかをテストするにはどうすればよいですか? を参照してください。

PerlのFAQおよび回答はPerlディストリビューションの一部です。次を実行すると、Perlに付属しているこの回答のバージョンを表示できます。

$ perldoc -q equal

あなたのターミナルで。

3
Sinan Ünür

Test :: Deep :: NoTest は同じ機能を持っています。

3
Adam Millerchip

速くて汚い、そして私はそれほど効率的ではないと確信しています:

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;
2
zakovyrya

@zakovyryaこの回答を参照してください: https://stackoverflow.com/a/2011443/2606517 キーの順序は内部データ構造からのものです。

0
Josefant