in reply to Using substr on Hash Keys

TMTOWTDI:

$hash{substr $_, 2} = delete $hash{$_} for keys %hash;

Update: Actually, this is the same solution as jettero wrote above, but I've made it more terse.

Replies are listed 'Best First'.
Re^2: Using substr on Hash Keys
by jettero (Monsignor) on Sep 10, 2008 at 19:53 UTC
    I was going to do something like this, but I couldn't reason out which of the delete vs the substr would happen first. It occurred to me, reading your post, that substr doesn't actually modify the string like splice modifies arrays -- so it doesn't matter.

    -Paul

      I was going to do something like this, but I couldn't reason out which of the delete vs the substr would happen first.

      Doesn't matter, unless you expect a collision between a new key and an old key. If that's the case, other solutions have the problem too. (The solution is to use another hash.)

      What does matter is that all the keys are fetched before any insertion into and deletion from the hash. And they are. for loads the entire list over which to iterate into memory before starting to loop.

        I was picturing it like this (incorrectly thinking substring would modify $_), where I think the order does matter, and I can't predict what would happen:
        $hash{ do{ $_ =~ s/(..)$//; $_ } } = delete $hash{ $_ } for keys % +hash;

        What appears to happen is that the lvalue is evaluated first, so I end up deleting the modified key into the new key position (leaving all the old keys in place and defining new keys to undef); but I couldn't have guessed until I tried it, so I'd tend to lean toward a for() loop like my first post.

        And I think that was jwkrahn's point too:

        $hash{ substr $_, 1, 20, "" } = delete $hash{ $_ } for keys %hash;

        -Paul

      Actually, substr can modify the string if you use the fourth argument.

        Yes, but hash keys aren't Perl strings, so keys actually returns a copy of the keys, so substr can only modify the copy, not the key itself.
      Thanks everyone for the replies. I love the 'TMTOWTDI' factor about Perl, but are both methods as efficient as each other?

        Does it matter? Which do you find more readable? Which are you most likely to use again correctly in the future without looking it up? Which do you think least requires a comment?


        Perl reduces RSI - it saves typing