in reply to re-key a hash

Here's my shot at doing it in a single step — but don't try this at home.

%hash = ( 0 .. keys( %hash ) - 1, @hash{ sort { $a <=> $b } keys %hash } )[ map +( $_, $_ + keys %hash ), 0 .. keys( %hash ) - 1 ];

Makeshifts last the longest.

Replies are listed 'Best First'.
Re^2: re-key a hash
by BrowserUk (Patriarch) on Aug 02, 2004 at 23:43 UTC

    Much better :)

    { local $_ = keys( %h ) -1; @h{ 0 .. $_ } = delete @h{ sort { $a<=>$b } keys %h }; }

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

      If we're using multiple statements anyway (not doing so was the point of my obscure ditty), I'd shuffle things around.

      { my @key = sort { $a <=> $b } keys %h; @h{ 0 .. $#key } = delete @h{ @key }; }

      That seems like a cleaner separation of concerns. The symmetry of the second line here seems more pleasing and makes it more robust — it remains valid regardless of how the list of keys is generated.

      Makeshifts last the longest.

Re^2: re-key a hash
by brool (Initiate) on Aug 03, 2004 at 01:05 UTC
    Let the garbage collector do the deletes... I know, I know, it's not the problem spec!
    my $count = 0; %hash = map { $count++ => $a{$_} } sort { $a <=> $b } keys %hash;

      There's no delete in mine either of course, and you still need two statements your way. :-) It's what I'd probably use in production code though.

      Makeshifts last the longest.

Re^2: re-key a hash
by Roy Johnson (Monsignor) on Aug 03, 2004 at 01:46 UTC
    CPU is no object:
    %hash = map { ($_, $hash{(sort keys %hash)[$_]}) } 0..keys(%hash)-1;

    Caution: Contents may have been coded under pressure.

      That is a bit silly… but I'll concede that it's less obscure than mine. :-)

      Makeshifts last the longest.

Re^2: re-key a hash
by ysth (Canon) on Aug 02, 2004 at 23:37 UTC
    Very nice!