【问题标题】:Compare deeply nested data structures ignoring array order比较忽略数组顺序的深层嵌套数据结构
【发布时间】:2017-07-19 01:32:13
【问题描述】:

我需要使用 perl 比较深度嵌套的数据结构。 这些结构可以包含标量、数组和散列。 我更喜欢 XS 实现。 数据最初以 JSON 形式到达。

在数据模式中,数组内的项目顺序无法保证,因此难以比较。

我尝试了 Test::Deep。当唯一的数组位于顶层时,该方法很容易,但当不区分顺序的数组嵌套在结构中更深时,该方法就很重了。

【问题讨论】:

  • 您心目中的比较类型是什么?检查数据结构是否相同?所有数组元素都相等,并且所有哈希键都匹配?
  • 是的,比较所有项目/哈希是否具有相同的键/值。包含相同元素的所有数组顺序不敏感。该方法获得 2 个引用(很像 Test::Deep)并计算出类型、嵌套和拓扑本身。差异应该可以退货或至少记录下来。
  • 数组可以包含除标量以外的其他东西吗? IE。子数组或哈希?如果是这样,您如何确定正确的顺序?例如。应该将哪个数组 ref 与哪个数组 ref 进行比较?

标签: arrays perl compare


【解决方案1】:

如果数组只能包含标量。您可以尝试使用Data::Compare。这是一个带有数值数组的示例。您需要为Data::compare 编写插件,更多信息请参见Data::Compare::Plugins

test.pl

use lib '.';
use strict;
use warnings;
use Data::Compare;

my $h1 = { a => {b => [2, 1, 3] }, c => 3};
my $h2 = { a => {b => [1, 2, 3] }, c => 3};

print 'The structures $h1 and $h2 are ',
  Compare($h1, $h2) ? "" : "not ", "identical.\n";

./Data/Compare/Plugins/ArrayBag.pm

package Data::Compare::Plugins::ArrayBag;

use strict;
use warnings;
use Data::Compare;

sub _register {
    return [
        ['ARRAY', 'ARRAY', \&array_compare],
    ];
}

sub array_compare {
    my($a1, $a2) = @_;

    return 0 if (scalar @$a1) != (scalar @$a2);
    my @ar1 = sort { $a <=> $b } @$a1;
    my @ar2 = sort { $a <=> $b } @$a2;
    for my $i (0..$#ar1 ) {
        return 0 if $ar1[$i] != $ar2[$i];
    }
    return 1;
}

_register();

输出来自运行test.pl

The structures $h1 and $h2 are identical.

【讨论】:

  • 请注意,如果数据是字符串而非数字,sort 可能需要更改为使用 cmp 而不是 &lt;=&gt;
  • 如何为包含哈希的数组添加相同的逻辑?
猜你喜欢
  • 2022-01-25
  • 1970-01-01
  • 2013-03-21
  • 1970-01-01
  • 2012-10-03
  • 2016-11-01
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多