How do I do a simple Perl hash equivalence comparison?

13,246

Solution 1

Something like cmp_deeply available in Test::Deep ?

Solution 2

I don't know if there's an easy way or a built-in package, and I don't know what happens when you just do %hash1 == %hash2 (but that's probably not it), but it's not terribly hard to roll your own:

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;
}

Untested, but should return 0 if the hashes have all the same elements and all the same values. This function will have to be modified to account for multidimensional hashes.

If you want something from a standard distribution, you could use Data::Dumper; and just dump the two hashes into two scalar variables, then compare the strings for equality. That might work.

There's also a package on CPAN called FreezeThaw that looks like it does what you want.

Note that to use the smart match (not repeated here because it's already posted), you will have to use feature; and it's only available for Perl 5.10. But who's still using Perl 5.8.8, right?

Solution 3

Thanks for your question.

I used Test::More::eq_hash as result.

Share:
13,246
cdleary
Author by

cdleary

Updated on June 04, 2022

Comments

  • cdleary
    cdleary about 2 years

    I'm wondering if there's an idiomatic one-liner or a standard-distribution package/function that I can use to compare two Perl hashes with only builtin, non-blessed types. The hashes are not identical (they don't have equivalent memory addresses).

    I'd like to know the answer for both for shallow hashes and hashes with nested collections, but I understand that shallow hashes may have a much simpler solution.

    TIA!

  • cdleary
    cdleary over 15 years
    Also the "==" comparison forces a scalar context, so it compares number of elements.
  • cdleary
    cdleary over 15 years
    Sure, I think Test::Deep::eq_deeply is exactly what I'm looking for!
  • visual_learner
    visual_learner over 15 years
    @cdleary: I said that because, as a user of Mac OS X, all OS X users are by default still using 5.8.8, unless they went out of their way to upgrade it.