Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Whay is the most elegant way to turn a hash inside out?

Tags:

hash

perl

What is the most elegant way to turn a hash inside out?

By that I mean replace keys with values and vice versa (assuming that all the values are 100% unique).

E.g.

Start with

my %start = (1=>"a", 2=>"b", 3=>"c");

# ...

# PROFIT: 
my %finish = ("c" => 3, "b" => 2, "a" => 1);

I know I can do it the brute force way:

foreach my $key (keys %start) {
    my $value = $start{$key};
    $finish{ $value } = $key;
}

But this can't be the most Perly-elegant way of doing so!

like image 633
Ike Avatar asked Feb 13 '12 21:02

Ike


2 Answers

reverse is probably among the most idiomatic ways:

my %finish = reverse %start;

This works, because reverse takes the %start hash as a list of the form (key1 value1 key2 value2... keyN valueN); then reverse reverses the list (valueN keyN ... value1 key1). Assigning that list to a hash variable then turns it into a hash with odd elements becoming keys and even elements becoming values

Or you can use map (less elegant but still idiomatic):

my %finish = map { ( $start{$_} => $_ ) } keys %start;
like image 74
DVK Avatar answered Nov 07 '22 20:11

DVK


my %start = (1=>"a", 2=>"b", 3=>"c");

my %finish;
@finish{values %start} = keys %start;
like image 29
cjm Avatar answered Nov 07 '22 21:11

cjm