我想知道是否有一个惯用的单行或标准分发包/函数,我可以用来比较两个Perl哈希只有内置的,非祝福的类型。哈希值不相同(它们没有等效的内存地址)。
我想知道浅层哈希和嵌套集合哈希的答案,但我知道浅哈希可能有一个更简单的解决方案。
TIA!
答案 0 :(得分:13)
在Test::Deep中可以使用cmp_deeply吗?
答案 1 :(得分:4)
[这是对删除答案的人的答复的回应。]
哦,哦!
%a ~~ %b && [sort values %a] ~~ [sort values %b]
不检查值是否属于相同的键。
#! perl
use warnings;
use strict;
my %a = (eat => "banana", say => "whu whu"); # monkey
my %b = (eat => "whu whu", say => "banana"); # gorilla
print "Magilla Gorilla is always right\n"
if %a ~~ %b && [sort values %a] ~~ [sort values %b];
答案 2 :(得分:1)
我不知道是否有简单的方法或内置的软件包,我不知道当你做%hash1 == %hash2
时会发生什么(但可能不是这样),但它并不是特别困难滚动你自己:
sub hash_comp (\%\%) {
my %hash1 = %{ shift };
my %hash2 = %{ shift };
foreach (keys %hash1) {
return 1 unless defined $hash2{$_} and $hash1{$_} == $hash2{$_};
delete $hash1{$_};
delete $hash2{$_};
}
return 1 if keys $hash2;
return 0;
}
未经测试,但如果哈希具有所有相同的元素和所有相同的值,则应返回0。必须修改此函数以考虑多维哈希。
如果你想要标准发行版的内容,你可以use Data::Dumper;
并将两个哈希值转换为两个标量变量,然后比较字符串的相等性。这可能有用。
CPAN上还有一个名为FreezeThaw
的软件包看起来像你想做的那样。
请注意,要使用智能匹配(此处不重复,因为它已经发布),您必须use feature;
并且它仅适用于Perl 5.10。但是谁还在使用Perl 5.8.8,对吧?
答案 3 :(得分:1)
感谢您的提问。
我使用了Test :: More :: eq_hash作为结果。
答案 4 :(得分:0)
浅浅的哈希:
(grep {exists %hash2{$_}} keys %hash1) > 0
答案 5 :(得分:0)
哈希可以被转换为数组,其中每个值都跟随其键(但您不会知道键的顺序)。所以:
( join("",sort(%hash1)) eq join("",sort(%hash2)) )
哦,等等,这是行不通的,因为有一些边缘情况,例如:
%hash1 = { 'aaa' => 'aa' };
%hash2 = { 'aa' => 'aaa' };
所以最好在join()中使用一个你知道永远不会出现在任何键或值中的字符。如果值是BLOB,那将是一个大问题,但对于其他任何事情,您可以使用NULL char“\ 0”。
( join("\0",sort(%hash1)) eq join("\0",sort(%hash2)) )
看起来有点难看,我知道,但它会检查两个哈希值是否相等,这是大多数人都在寻找的。 p>
答案 6 :(得分:0)
您可以在eq_deeply中使用Test::Deep::NoTest。它只返回一个你可以检查的布尔值,而没有main module的测试功能的额外开销。
答案 7 :(得分:-1)
将哈希转换为xml文件并进行比较,是的,您可以使用多级。
sub isEqualHash
{
my ($self,$hash1, $hash2) = @_;
my $file1 = "c:/neo-file1.txt";
my $file2 = "c:/neo-file2.txt";
my $xmlObj = XML::Simple->new();
my $dummy_file = $xmlObj->XMLout($hash1,OutputFile => $file1);
my $dummy_file = $xmlObj->XMLout($hash2,OutputFile => $file2);
open FILE, "<".$file1;
my $file_contents1 = do { local $/; <FILE> };
close(FILE);
open FILE, "<".$file2;
my $file_contents2 = do { local $/; <FILE> };
close(FILE);
if($file_contents1 eq $file_contents2)
{
return "Passed";
}
else
{
return "Failed";
}
}