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

Hi Monks,
Is there a way to change the key names in a hash. Say, I have
$hash{'key1'} = "Value1" ;
What I need is to change the key 'key1' to 'key2'. Offcourse this can be achieved by
$hash{'key2'} = $hash{'key1'}; delete $hash{'key1'} ;
Is there any other way other than adding and deleting elements?
Many thanks for your time.

Replies are listed 'Best First'.
Re: Modifying the keys in a hash
by Sidhekin (Priest) on Feb 23, 2007 at 10:10 UTC

    No other way. Sorry. However, you can make it less clumsy (at least avoid repeating $hash{'key1'}) by using the return value from delete:

    $hash{'key2'} = delete $hash{'key1'};

    print "Just another Perl ${\(trickster and hacker)},"
    The Sidhekin proves Sidhe did it!

      Thanks for the reply.
Re: Modifying the keys in a hash
by sluap (Sexton) on Feb 23, 2007 at 14:22 UTC
    Hi, You could treat the hash as an array and modify the key with something like:
    %hash = map { s/^key1$/new_key2/; $_; } %hash;
    However, I'm not sure I would recommend it, as I don't think it makes what you are trying to do any clearer, and it has the potential to modify values that also match the regex!
      ... map { s/^key1$/new_key2/; $_; } ...
      In general, this idiom is a bad idea, because the value of $_ is a reference to the original data. So not only do you have a new value on your output, you have also edited the values on the input (if possible)!

      If you want to make changes like that, make a local copy of $_:

      ... map { local $_ = $_; s/^key1$/new_key2/; $_; } ...
        That's interesting - I wondered if that could be used to modify the hash key without creating a copy of the whole hash so tried:
        use Data::Dump qw(dump); my %hash = ( key1 => 'Value1', key2 => 'Value2', key3 => 'Value3', ); print "old hash is " . dump(\%hash) ."\n"; map { s/2/_two/; } %hash; print "new hash is " . dump(\%hash) ."\n"; # output is: # old hash is { key1 => "Value1", key2 => "Value2", key3 => "Value3" } # new hash is { key1 => "Value1", key2 => "Value_two", key3 => "Value3 +" }
        How come 'Value2' is changed to 'Value_two', but 'key2' is unchanged?

        (Note: I wasn't suggesting that this method should be used for modifying a hash key, but was trying to rise to the challenge of suggesting another method other than copy and delete!)

      You could treat the hash as an array and modify the key

      Sure you could, but why?

      Re-construct the entire hash to modify just one key? That's feasible, but only for small hashes, since you are duplicating all keys and values of the hash into a temporary list. Pretty much overhead.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}