in reply to re-key a hash

A hash is great if the data is sparsely populated, but if you make the keys sequential integers, why not go with an array?

my @array = @hash{ sort {$a <=> $b} keys %hash};

Incidentally, note that you're deleting hash elements while iterating over it. You're not supposed to do that.

Update: To keep a hash, try something like this:

my %hash2; @hash2{ 0 .. (keys %hash)-1 } = map { $hash{$_} } sort {$a <=> $b} key +s %hash;

It's really ugly, though :)

Update 2 ysth and Aristotle both caught me sleeping. Pay no attention to the man in the classical poet outfit.

Cheers,
Ovid

New address of my CGI Course.

Replies are listed 'Best First'.
Re^2: re-key a hash
by Aristotle (Chancellor) on Aug 02, 2004 at 21:46 UTC
    @hash2{ 0 .. (keys %hash)-1 } = map { $hash{$_} } sort {$a <=> $b} key +s %hash;

    You had it right before; why did you think you need the map there?

    @hash2{ 0 .. (keys %hash)-1 } = @hash{ sort { $a <=> $b } keys %hash } +;

    I'm too lazy to verify, but I think you don't need to assign to a separate hash if you do it this way, either. The list should be assigned atomically once it is built completely.

    Makeshifts last the longest.

Re^2: re-key a hash
by ysth (Canon) on Aug 02, 2004 at 21:41 UTC
    You are explicitly allowed to delete each element as you iterate; you ought not to make other changes (as this code does).
      I can understand the caveat if you're iterating over values or with each, but sort keys is not a hash iterator.

      We're not really tightening our belts, it just feels that way because we're getting fatter.
        You're right; I misread the loop. There's no problem at all, then, except that the code doesn't do what he wants.