in reply to Re: Compare two Hashes of Hashes
in thread Compare two Hashes of Hashes

Thank you Kennethk for reply. Sorry I forgot to add what I tried. I made a function to compare first level key and value of two hashes but I am struggling to check for second level values. Can you please help?

comp (\% hash1, \%hash2); sub comp { my $hash1 = shift; my $hash2 = shift; if( keys %{$hash1} != keys %{$hash2} ) { print "Hash1 has ", scalar(keys %{$hash1}), " units but hash2 has ", scalar(keys %{$hash2}), "\n"; } for my $key_hash1 (sort {lc($a) cmp lc($b) } keys %{$hash1} ) { if( ! exists $hash2->{$key_hash1} ) { print "Hash1 contains unit '$key_hash1' but hash2 has no such un +it\n"; next; } if( $hash1->{$key_hash1} ne $hash2->{$key_hash1} ) { print "Both hashes have '$key_hash1' as a unit ", "but hash1's value is '$hash1->{$key_hash1}' ", "and hash2's value is '$hash2->{$key_hash1}'\n"; } } }

Replies are listed 'Best First'.
Re^3: Compare two Hashes of Hashes
by kennethk (Abbot) on Dec 16, 2016 at 17:21 UTC
    Thank you for posting that code. Note that with the block
    for my $key_hash1 (sort {lc($a) cmp lc($b) } keys %{$hash1} ) { if( ! exists $hash2->{$key_hash1} ) { print "Hash1 contains unit '$key_hash1' but hash2 has no such un +it\n"; next; }
    you will check if %hash2 is missing keys from %hash1, but you lack code to do the reverse check. So you probably want to add something like:
    for my $key_hash2 (sort {lc($a) cmp lc($b) } keys %{$hash2} ) { if( ! exists $hash1->{$key_hash2} ) { print "Hash1 contains unit '$key_hash2' but hash1 has no such un +it\n"; } }
    For adding another layer of checks, you need to replace your value check
    if( $hash1->{$key_hash1} ne $hash2->{$key_hash1} ) { print "Both hashes have '$key_hash1' as a unit ", "but hash1's value is '$hash1->{$key_hash1}' ", "and hash2's value is '$hash2->{$key_hash1}'\n"; }
    with another loop over the keys of the hashes, very much like you've done already.
    for my $key_hash1 (sort {lc($a) cmp lc($b) } keys %{$hash1} ) { if( ! exists $hash2->{$key_hash1} ) { print "Hash1 contains unit '$key_hash1' but hash2 has no such un +it\n"; next; } for my $key_hash1_tier2 (sort {lc($a) cmp lc($b) } keys %{$hash1-> +{$key_hash1}} ) { if( ! exists $hash2->{$key_hash1}{$key_hash1_tier2} ) { print "Hash1 $key_hash1 contains unit '$key_hash1_tier2' but h +ash2 has no such unit\n"; next; } if( $hash1->{$key_hash1}{$key_hash1_tier2} ne $hash2->{$key_hash +1}{$key_hash1_tier2} ) { print "Both hashes have '$key_hash1'-'$key_hash1_tier2' as a u +nit ", "but hash1's value is '$hash1->{$key_hash1}{$key_hash1_t +ier2}' ", "and hash2's value is '$hash2->{$key_hash1}{$key_hash1_t +ier2}'\n"; } } }
    subject to the same criticism I made before about not checking which elements are in %hash2 but not %hash1. You can see this clearly if you reverse the order of the arguments to comp.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.