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

Hi all,
I have a an array @hash = ("name" =>"john", "age"=>"25", "job"=>"programer", "location"=>"US");
My question is
Create a hash that stores all key/values swapped using @hash.
I solved like this
@hash = ("name" =>"john", "age"=>"25", "job"=>"programer", "location" +=>"US"); %test = @hash; %test_1 = (); foreach $key (keys %test) { $val = $test{$key}; $test_1{$val} = $key; }

Is it correct, here I used 2 arrays. Can you please provide a correct solution
Thanks
John

Replies are listed 'Best First'.
Re: key-values swapped
by thinker (Parson) on Feb 18, 2005 at 09:44 UTC

    You could do

    %test = reverse @hash;

    but you would have to look out for collisions with the keys, which could cause you to lose values

    cheers

    thinker

      Hi thinker,
      Your solution is good. Thank you.
      Regards,

      Talking about hurting one's head ...

      Reversing a hash, you have to watch out for value collisions which could cause you to lose keys. At least, from the perspective of the original hash. Just trying to think about both hashes at the same time in the context of keys and values is giving me a headache. Where is my caffeine?

      Update for the humour-impaired: This is a joke. Relax. ;-)

Re: key-values swapped
by Corion (Patriarch) on Feb 18, 2005 at 09:44 UTC

    If you are not sure if your solution is correct you need to ask yourself the following questions:

    1. What do I expect?
      Manually create the correct solution for simple input parameters, on paper.
    2. What does my current solution produce?
      Find a way to verify your paper solutions with your programmatic solution. With Perl, the module Data::Dumper is very helpfull when looking at data structures:
      use Data::Dumper; print Dump \%test; print Dump \%reversed_test; # a better name than %test1
    3. Are the examples I tested generic enough to cover all cases?
      This is hard - you need to think about the cases that can possibly occur in your input data, and then consider how your code handles these cases to produce the output. In many cases of program verification, it helps to find invariants, that is, things that always are true. For example, for a hash with unique keys and unique values, reverse_hash( reverse_hash( %test )) should always be equal to the hash %test itself. Can you think about an invariant that is true for a hash with duplicate values? Can you think about an invariant that is true for a hash with duplicate keys?
      Hi Corion,
      Thanks for your valuable information.
Re: key-values swapped
by Fletch (Bishop) on Feb 18, 2005 at 17:42 UTC

    Modulo worrying about duplicate values, just use a slice.

    my %hsah; @hsah{ values %hash } = keys %hash;
Re: key-values swapped
by Cody Pendant (Prior) on Feb 19, 2005 at 09:30 UTC
    Maybe the best way to do it, to avoid clobberage, would be to make a hash of arrays?

    So that for instance,

    name => "john", age => "25", supervisor => "john", job => "programmer", location => "US"

    would become

    john => ['name','supervisor'], 25 => ['age'], programmer => ['job'], us => ['location']

    that way, if any of your arrays had two or more elements, you'd know something had got clobbered...



    ($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss')
    =~y~b-v~a-z~s; print
Re: key-values swapped
by sh1tn (Priest) on Feb 18, 2005 at 09:48 UTC
    %hash = ("name" =>"john", "age"=>"25", "job"=>"programer", "locatio +n"=>"US"); %reverse = reverse%hash; print "$_ \t $hash{$_} $/" for keys %hash; print "$_ \t $reverse{$_} $/" for keys %reverse;