Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json Perl-比较两个嵌套哈希_Json_Perl_Hash_Perl Data Structures - Fatal编程技术网

Json Perl-比较两个嵌套哈希

Json Perl-比较两个嵌套哈希,json,perl,hash,perl-data-structures,Json,Perl,Hash,Perl Data Structures,这是我的场景,其中有2个哈希已从2个JSON文件中解码 我有两个复杂的散列 $hash1 = {k1=> { k11 => v1, k12 => v2}, k2 => { k21 => [v1, v2, v3] }} $hash2 = {k1=> { k11 => v1, k12 => v2}, k2 => { k21 => [v3, v2, v1] }} 我想比较这两个哈希是否相等,并使用Data::compare的比较和Test:

这是我的场景,其中有2个哈希已从2个JSON文件中解码

我有两个复杂的散列

$hash1 = {k1=> { k11 => v1, k12 => v2}, k2 => { k21 => [v1, v2, v3] }}
$hash2 = {k1=> { k11 => v1, k12 => v2}, k2 => { k21 => [v3, v2, v1] }}
我想比较这两个哈希是否相等,并使用Data::compare的比较和Test::More的比较。两者都不会忽略数组的顺序。
我想忽略键“k21”的数组值顺序进行比较。
我的应用程序通过“键%hash”填充数组,该数组给出随机顺序。
尝试对Data::Compare进行“忽略\u哈希\u键”,但我的哈希有时可能很复杂,不想忽略

键“k21”有时也可以有散列数组

$hash3 = {k1=> { k11 => v1}, k2 => { k21 => [{v3 => v31}, {v2 => v22}] }}
如何通过忽略数组顺序来比较这种复杂的散列。

您可以使用,它提供了
cmp\u
。它比Test::more的
更通用

use Test::Deep;

my $hash1 = {
    k1 => { k11 => 'v1', k12 => 'v2' }, k2 => { k21 => [ 'v1', 'v2', 'v3' ] } };
my $hash2 = {
    k1 => { k11 => 'v1', k12 => 'v2' }, k2 => { k21 => bag( 'v3', 'v2', 'v1' ) } };

cmp_deeply( $hash1, $hash2, );
诀窍是忽略元素顺序的

这将进行包比较,即比较两个数组,但忽略元素的顺序[…]


更新:来自:

如何动态打包散列中的所有数组引用

对Test::Deep代码的一些挖掘表明,可以覆盖它。我首先查看了它本身,发现有一个用于处理数组的。处理T::D内部内容的所有包都有。所以这就是我们需要参与的地方

临时重写东西,而不是搞乱typeglobs,这很好

基本上,我们需要做的就是将
Test::Deep::arrayelementsonly
中对
Test::Deep::Array::down
的最后一行的调用替换为对
bag()
的调用。其余的只是复制(缩进是我的)。对于小型软件来说,对现有代码稍加修改就可以了,这通常是最简单的方法

use Test::Deep;
use Test::Deep::Array;
use Sub::Override;

my $sub = Sub::Override->new(
    'Test::Deep::Array::descend' => sub {
        my $self = shift;
        my $got  = shift;

        my $exp = $self->{val};

        return 0 unless Test::Deep::descend( 
             $got, Test::Deep::arraylength( scalar @$exp ) );

        return 0 unless $self->test_class($got);

        return Test::Deep::descend( $got, Test::Deep::bag(@$exp) );
    }
);

my $hash1 = {
    k1 => { k11 => 'v1', k12 => 'v2' },
    k2 => { k21 => [ 'v1', 'v2', 'v3' ] }
};
my $hash2 = {
    k1 => { k11 => 'v1', k12 => 'v2' },
    k2 => { k21 => [ 'v3', 'v2', 'v1' ] }
};

cmp_deeply( $hash1, $hash2 );
这将使测试通过


请确保通过取消定义
$sub
或使其超出范围来重置覆盖
,否则,如果测试套件的其余部分也使用test::Deep,您可能会有一些奇怪的惊喜。

感谢simbabque给出的答案,如何动态地将所有数组引用打包到哈希中$hash2是生成的输出并包含嵌套的哈希,我如何动态地告诉cmp_任何数组比较都应该通过bag完成,或者我应该遍历哈希并进行单独的bag比较。感谢@simbabque,我如何动态地将哈希中的所有数组引用打包<代码>我的$arr_of_h1={'a'=>[1,2,3],b=>[{{2=>1},{1=>1},{3=>1}]}
my$arr\u of_h2={'a'=>[1,2,3],b=>[{{2=>1},{3=>1},{1=>1}]}
cmp_深($arr_of_h1->{b},bag(@{$arr_of_h2->{b}),“数组相等”)上面的stmt工作,但希望下面通过执行行李比较来工作<代码>cmp_($arr_of_h1,$arr_of_h2,“散列相等”)@user我想你必须构建它。或者可能有某种挂钩机制。你读过完整的测试::深度文档了吗?否则,您可以使用或类似的方法来构建遍历。我建议你问一个新问题,因为它与这里的初始问题不同。@user查看我的更新。事实上,我最近在一次测试中遇到了同样的问题,但我决定更改测试用例。弄明白这一点很有趣。谢谢你的回答。通过重写,我可以通过忽略数组的顺序来比较2个复杂哈希。