我想比较数组的两个哈希,看看它们是否相等。也就是说,键值应包含相同的元素。
my %h1 = (
w1 => ['3','1','2'],
e2 => ['6','2','4'],
r1 => ['8', '1'],
);
my %h2 = (
w1 => ['3','1','2'],
e2 => ['6','2','4'],
r1 => ['8','1'],
);
my %h3 = (
w1 => ['3','1','2'],
e2 => ['6','2','4'],
r1 => ['4','1'],
);
my $i = 0;
foreach ( keys %h2 ){
my $conditional = scalar keys %h2; # 3
if ([sort @{$h1{$_}}] ~~ [sort @{$h2{$_}}]) {
$i++;
}
if ($i eq $conditional){
print "true\n";
}
}
比较%h1
和%h2
应该返回true,因为它们是相等的。比较%h1
和%h3
不会打印任何内容。 1)有更好的方法吗?
修改
我想在不使用模块中的函数的情况下执行此操作。
答案 0 :(得分:4)
尝试使用Test::Deep::NoTest来处理Test::Deep所做的一切,除了它只返回true或false而不输出TAP测试。
print "true" if eq_deeply(\%h1, \%h2)
答案 1 :(得分:3)
Data::Dumper
是一个序列化数据结构的核心模块。然后,您可以测试序列化以确保字符串相等。
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
if (Dumper(\%hash1) eq Dumper(\%hash2)) {
print "hashes are equal\n";
}
如果偶数Data::Dumper
是禁止的,请编写自己的序列化例程,将HoA转换为字符串,并比较字符串。请确保您不会被返回哈希键的随机顺序绊倒(这就是上面示例中$Data::Dumper::Sortkeys=1
行的用途)。
答案 2 :(得分:1)
我为每个操作创建单独的subs:测试数组是否相等且是否为哈希:
sub is_arrays_equal($$) {
my ($a, $b) = @_;
if (scalar @$a != scalar @$b) {
return 0;
}
for my $i (0 .. $#{$a}) {
if ($a->[$i] ne $b->[$i]) {
return 0;
}
}
return 1;
}
sub is_hoa_equal($$) {
my ($a, $b) = @_;
if (scalar(keys %$a) != scalar(keys %$b)) {
return 0;
}
for my $k (keys %$a) {
if (exists $b->{$k}) {
if (ref $a->{$k} ne 'ARRAY' || ref $b->{$k} ne 'ARRAY' || !is_arrays_equal($a->{$k}, $b->{$k})) {
return 0;
}
}
else {
return 0;
}
}
return 1;
}
注意:将'ne'更改为'!='或添加逻辑以比较标量值。
由于对每个阵列和其他繁重的数据处理进行排序,您的解决方案并不好。如果你需要对所有类型的哈希进行相等性测试(不仅仅是我的解决方案中的HoA),只需添加标量测试和哈希测试,这将是主要子的递归调用,类似:
sub arrays_equal {
my ( $a, $b ) = @_;
if ( scalar @$a != scalar @$b ) {
return 0;
}
for my $i ( 0 .. $#{$a} ) {
my $va = $a->[$i];
my $vb = $b->[$i];
if ( ref $va ne ref $vb ) {
return 0;
}
elsif ( ref $va eq 'SCALAR' && $va ne $vb ) {
return 0;
}
elsif ( ref $va eq 'ARRAY' && !arrays_equal( $va, $vb ) ) {
return 0;
}
elsif ( ref $va eq 'HASH' && !hashes_equal( $va, $vb ) ) {
return 0;
}
}
return 1;
}
sub hashes_equal {
my ( $a, $b ) = @_;
if ( scalar( keys %$a ) != scalar( keys %$b ) ) {
return 0;
}
for my $k ( keys %$a ) {
if ( exists $b->{$k} ) {
my $va = $a->{$k};
my $vb = $b->{$k};
if ( ref $va ne ref $vb ) {
return 0;
}
elsif ( ref $va eq 'SCALAR' && $va ne $vb ) {
return 0;
}
elsif ( ref $va eq 'ARRAY' && !arrays_equal( $va, $vb ) ) {
return 0;
}
elsif ( ref $va eq 'HASH' && !hashes_equal( $va, $vb ) ) {
return 0;
}
}
else {
return 0;
}
}
return 1;
}
此代码将标量检查为字符串。您可以像这样添加is_number或smth,或者只是将'ne'更改为'!='(但是如果不仅有数字,请注意警告)。