### Re: How to test equality of hashes?

by jeroenes (Priest)
 on Jun 20, 2001 at 12:05 UTC ( #89938=note: print w/replies, xml ) Need Help??

in reply to How to test equality of hashes?

bikeNomad's solution 1 does not take into account the probability that the values may be the same, but that they are not tied to the same key. So:
```my @k1 = keys(%hash1);
my @k2 = keys(%hash2);

# do they have the same number of elements?
if (@k1 != @k2) { # they're different...
}

# are the keys the same?
if ((join \$; , sort @k1 )
ne join \$; , sort @k2)) { #they're different
}

# are the values the same?
if ( scalar grep { \$hash1{\$_} ne \$hash2{\$_} } @k1 )
{ #they're different
}
Number warning still applies.

Jeroen

Replies are listed 'Best First'.
Re: Re: How to test equality of hashes?
by acser (Novice) on Jun 20, 2001 at 17:56 UTC
Here's the subroutine I came up with. Thanks for everyone who responded. I could never get the flattening the array method to work. It is not very elegant and probably slow, but this is the only solution I could find that prints the right answer:
```equal

non equal

equal
```#!/usr/bin/perl
\$HASH_SIZE = 100;
%hash1;
%hash2;

for (\$i=0; \$i < \$HASH_SIZE; \$i++) {
\$hash1{"i=\$i"} = "j=\$i";
}

%hash2 = %hash1;

if (&hasheq(\%hash1, \%hash2)) {
print "\nequal\n";
} else
{
print "\nnon equal\n";
}

\$hash2{"anotherone"} = "anotherONE";

if (&hasheq(\%hash1, \%hash2)) {
print "\nequal\n";
} else
{
print "\nnon equal\n";
}

\$hash1{"anotherone"} = "anotherONE";

if (&hasheq(\%hash1, \%hash2)) {
print "\nequal\n";
} else
{
print "\nnon equal\n";
}

sub hasheq {

my (\$ha1, \$ha2) = @_;
my %h1 = %\$ha1;
my %h2 = %\$ha2;

my @k1 = keys(%h1);
my @k2 = keys(%h2);
# do they have the same number of elements?
if (@k1 != @k2) {
return 0;
}

# are the keys the same?
if ((join '/' , sort @k1 ) ne (join '/' , sort @k2)) {
return 0;
}

# are the values the same?
if ( scalar grep { \$h1{\$_} ne \$h2{\$_} } @k1 )
{
return 0;
}

return 1;

}
Nice. I can't see this kind of follow-ups often enough!

1. use strict warnings and diagnostics or die. These are your friends on the long run.
2. You declare 2 vars without need:
```  my %h1 = %{ \$_[0] }; #h2 similar
3. Check whether your refs are defined:
```  my %h1 = (defined \$_[0] and ref \$_[0]) ? %{ \$_[0] } : ();
This will make the code more portable/general/cleaner. You may add an extra check for hashiness.
4. I just realized that this code can't distinguish between undefined or empty, so the grep becomes:
```  scalar grep {
my (\$a, \$b) = ( \$h1{\$_}, \$h2{\$_} );
( not defined \$a and defined \$b )
or
( not defined \$b and defined \$a )
or
\$a ne \$b
} @k1
Had to think extra carefully there!

Hope this helps,

Jeroen

Create A New User
Node Status?
node history
Node Type: note [id://89938]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2018-05-25 15:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
World peace can best be achieved by:

Results (188 votes). Check out past polls.

Notices?