Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Swapping keys and values in a hash with slices

by pernod (Chaplain)
on Oct 20, 2004 at 10:25 UTC ( [id://400804]=perlquestion: print w/replies, xml ) Need Help??

pernod has asked for the wisdom of the Perl Monks concerning the following question:

From perlfunc on the values function:

The values are returned in an apparently random order. The actual random order is subject to change in future versions of perl, but it is guaranteed to be the same order as either the keys or each function would produce on the same (unmodified) hash.

I think this means that I can (safely) do the following to build a new hash where the key/value pairs have switched roles (ie. for each pair, the new hash uses the value as key, and the key as value):

use Data::Dump qw( dump ); my %hash = ( 1 => "Piker", 2 => "Vin", 3 => "Sang" ); my %revhash; @revhash{ values %hash } = keys %hash; print dump( \%hash ), "\n"; print dump( \%revhash ), "\n";

Have I missed something regarding the hash iterators, or is this an acceptable way of doing things? I am well aware of other solutions to this problem using loops and map, but I'm curious and trying to learn something on slices.

pernod
--
Mischief. Mayhem. Soap.

Replies are listed 'Best First'.
Re: Swapping keys and values in a hash with slices
by tomhukins (Curate) on Oct 20, 2004 at 10:31 UTC

    This seems reasonable enough to me, with the usual caveat that you will lose information if multiple elements share the same value.

    I would never use this code in production, though. You mention other solutions using loops and map, but I find the %revhash = reverse %hash idiom more elegant.

Re: Swapping keys and values in a hash with slices
by ihb (Deacon) on Oct 20, 2004 at 10:39 UTC

    It is an acceptable way and typically

    $large{keys %foo} = $values %foo;
    is used when you want to add one hash to another (large) hash, avoiding to do
    %large = (%large, %other)
    which does unnecessary copying.

    As tomhukins pointed out, there are easier ways of doing what you're doing.

    ihb

    See perltoc if you don't know which perldoc to read!
    Read argumentation in its context!

Re: Swapping keys and values in a hash with slices
by pg (Canon) on Oct 20, 2004 at 10:27 UTC

    But nobody promised you that keys and values would return in the same order though ;-)

    use Data::Dump qw( dump ); my %hash = ( 1 => "Piker", 2 => "Vin", 3 => "Sang" ); my %revhash; $revhash{$hash{$_}} = $_ for (keys(%hash)); print dump( \%hash ), "\n"; print dump( \%revhash ), "\n";
    Update:

    Forget about this, just use reverse as tomhukins said below.

      nobody promised you that keys and values would return in the same order

      Yes, they did. Read the quoted docs more carefully:

      The values are returned in an apparently random order. The actual random order is subject to change in future versions of perl, but it is guaranteed to be the same order as either the keys or each function would produce on the same (unmodified) hash.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2024-04-20 01:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found