Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re: How to test equality of hashes?

by jeroenes (Priest)
on Jun 20, 2001 at 12:05 UTC ( [id://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!

      A few comments, naturally:

      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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://89938]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-04-16 04:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found