You don't need to make a list of the records. Just sort the keys according to the corresponding record values, like this:
where extract is some function defined by you and that you apply to record values to get whatever you want the sorting to reflect. If extract returns strings that you want sorted alphabetically instead of numerically, then use cmp instead of <=>. And if you just want the sorting for the records to be plain ol' alphabetical sorting, then make thatmy @sorted_keys = sort { extract( $hash{ $a } ) <=> extract( $hash{ $b } ) } keys %has +h; for my $key ( @sorted_keys ) { # whatever }
Or you can optimize things further by using the Schwartzian Transform:my @sorted_keys = sort { $hash{ $a } cmp $hash{ $b } } keys %hash; for my $key ( @sorted_keys ) { # whatever }
or any other sort optimization technique.my @sorted_keys = map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [ $_, extract( $hash{ $_ } ) ] } keys %hash;
The important thing is that you are sorting the keys, even if the criterion for this sort is based on the associated values.
More generally, it is very common to want to sort a collection of items ($z, $y, $x, $w, ...) based on the values (f($z), f($y), f($x), f($w), ...) of some function f applied to those items. For example, if you want to sort strings without regard for their case, that function f could be uc (or equivalently lc). Then you just do
ormy @sorted = sort { f($a) cmp f($b) } @unsorted;
The important point is that what ends up in the @sorted arrays is not the f($z), f($y), f($x)... but the original $z, $y, $x,... (except that now they are sorted).my @sorted = sort { f($a) <=> f($b) } @unsorted;
And the second important point is that "dereferencing a hash key" is in this case conceptually no different from applying some function to the keys. I.e. f for this case could be defined as
Of course, a function f like the one above that does nothing to the hash value is usually not very useful, since we may as well just use $hash{ $key } directly.sub f { my $key = shift; return $hash{ $key }; }
the lowliest monk
In reply to Re: sorting a hash
by tlm
in thread sorting a hash
by Ben Win Lue
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |