develooper Front page | perl.beginners | Postings from August 2009

Inverting a hash safely

Thread Next
Ed Avis
August 3, 2009 04:40
Inverting a hash safely
Message ID:
The standard answer on how to invert a hash, so that keys become values and vice
versa, is to use reverse:

    my %reversed = reverse %hash;

The standard answer also mentions some caveats, most importantly that if the
original hash is not one-to-one, then some entries will be lost:

    use Data::Dump qw(dump);
    my %hash (a => 1, b => 2, c => 1);
    my %reversed = reverse %hash;
    print dump \%reversed;

In fact, it is not defined which of 'a' and 'c' will be kept and which will be
dropped.  So it's unlikely you would want to use reverse on a hash unless you
were certain it had no duplicate values, or you were equally certain that losing
some values didn't matter.

I have been bitten by bugs in my code where I assumed a hash was one-to-one, so
I could safely reverse it, but then later this assumption became incorrect.
It was my fault really, as the assumption wasn't checked anywhere in the code.
If you assume something like this you really should check it, both to catch
bugs in the future and to serve as documentation (documenting something in code
is usually better than putting it in a comment).

My question is, does there exist a 'safe hash invert' function in some CPAN
module?  I was imagining something like

    my %hash = (a => 1, b => 2);
    my %reverse = safe_hash_invert %hash; # works fine

    $hash{c} = 1;
    %reverse = safe_hash_invert %hash; # throws an error 'duplicate values...'

I see Hash::Util and Hash::MoreUtils on CPAN but neither provides such a
function.  Before I write one myself I wanted to check if there is already
a standard implementation.

Ed Avis <>

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About