|
Posted by nolo contendere on May 23, 2008, 9:30 am
Please log in for more thread options
> This is an excerpt from the latest version perlfaq4.pod, which
> comes with the standard Perl distribution. These postings aim to
> reduce the number of repeated questions as well as allow the community
> to review and update the answers. The latest version of the complete
> perlfaq is athttp://faq.perl.org.
>
> --------------------------------------------------------------------
>
> 4.59: How do I sort a hash (optionally by value instead of key)?
>
> =A0 =A0 (contributed by brian d foy)
>
> =A0 =A0 To sort a hash, start with the keys. In this example, we give the =
list
> =A0 =A0 of keys to the sort function which then compares them ASCIIbetical=
ly
> =A0 =A0 (which might be affected by your locale settings). The output list=
has
> =A0 =A0 the keys in ASCIIbetical order. Once we have the keys, we can go t=
hrough
> =A0 =A0 them to create a report which lists the keys in ASCIIbetical order=
.
>
> =A0 =A0 =A0 =A0 =A0 =A0 my @keys =3D sort { $a cmp $b } keys %hash;
>
> =A0 =A0 =A0 =A0 =A0 =A0 foreach my $key ( @keys )
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printf "%-20s %6d\n", $key, $hash{=
$key};
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
>
> =A0 =A0 We could get more fancy in the "sort()" block though. Instead of
> =A0 =A0 comparing the keys, we can compute a value with them and use that =
value
> =A0 =A0 as the comparison.
>
> =A0 =A0 For instance, to make our report order case-insensitive, we use th=
e "\L"
> =A0 =A0 sequence in a double-quoted string to make everything lowercase. T=
he
> =A0 =A0 "sort()" block then compares the lowercased values to determine in=
which
> =A0 =A0 order to put the keys.
>
> =A0 =A0 =A0 =A0 =A0 =A0 my @keys =3D sort { "\L$a" cmp "\L$b" } keys %hash=
;
>
> =A0 =A0 Note: if the computation is expensive or the hash has many element=
s, you
> =A0 =A0 may want to look at the Schwartzian Transform to cache the computa=
tion
> =A0 =A0 results.
>
> =A0 =A0 If we want to sort by the hash value instead, we use the hash key =
to
> =A0 =A0 look it up. We still get out a list of keys, but this time they ar=
e
> =A0 =A0 ordered by their value.
>
> =A0 =A0 =A0 =A0 =A0 =A0 my @keys =3D sort { $hash <=3D> $hash } ke=
ys %hash;
>
> =A0 =A0 From there we can get more complex. If the hash values are the sam=
e, we
> =A0 =A0 can provide a secondary sort on the hash key.
>
> =A0 =A0 =A0 =A0 =A0 =A0 my @keys =3D sort {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 $hash <=3D> $hash
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 or
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "\L$a" cmp "\L$b"
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } keys %hash;
>
> --------------------------------------------------------------------
>
> The perlfaq-workers, a group of volunteers, maintain the perlfaq. They
> are not necessarily experts in every domain where Perl might show up,
> so please include as much information as possible and relevant in any
> corrections. The perlfaq-workers also don't have access to every
> operating system or platform, so please include relevant details for
> corrections to examples that do not work on particular platforms.
> Working code is greatly appreciated.
>
> If you'd like to help maintain the perlfaq, see the details in
> perlfaq.pod.
really? is this some sort (har har) of perverse humor? or is there
some intelligence that does NLP on the posts to figure out which FAQ
to post? and no, i'm not paranoid--they really are out to get me.
|