Click here to get back home

FAQ 4.59 How do I sort a hash (optionally by value instead of key)?

 HomeNewsGroups | Search | About
 comp.lang.perl.misc    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
FAQ 4.59 How do I sort a hash (optionally by value instead of key)? PerlFAQ Server 05-23-2008
Get Chitika Premium
Posted by PerlFAQ Server on May 23, 2008, 9:03 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 at http://faq.perl.org .

--------------------------------------------------------------------

4.59: How do I sort a hash (optionally by value instead of key)?

(contributed by brian d foy)

To sort a hash, start with the keys. In this example, we give the list
of keys to the sort function which then compares them ASCIIbetically
(which might be affected by your locale settings). The output list has
the keys in ASCIIbetical order. Once we have the keys, we can go through
them to create a report which lists the keys in ASCIIbetical order.

my @keys = sort { $a cmp $b } keys %hash;

foreach my $key ( @keys )
{
printf "%-20s %6d\n", $key, $hash;
}

We could get more fancy in the "sort()" block though. Instead of
comparing the keys, we can compute a value with them and use that value
as the comparison.

For instance, to make our report order case-insensitive, we use the "\L"
sequence in a double-quoted string to make everything lowercase. The
"sort()" block then compares the lowercased values to determine in which
order to put the keys.

my @keys = sort { "\L$a" cmp "\L$b" } keys %hash;

Note: if the computation is expensive or the hash has many elements, you
may want to look at the Schwartzian Transform to cache the computation
results.

If we want to sort by the hash value instead, we use the hash key to
look it up. We still get out a list of keys, but this time they are
ordered by their value.

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

From there we can get more complex. If the hash values are the same, we
can provide a secondary sort on the hash key.

my @keys = sort {
$hash <=> $hash
or
"\L$a" cmp "\L$b"
} 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.

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.

Posted by brian d foy on May 23, 2008, 6:18 pm
Please log in for more thread options
In article

>
> 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.

I'm not sure what you are asking. The FAQ are posted sequentially.
Since the answers are to frequently asked questions, it's expected that
the answer would show up at the same time as someone asks the
question.

Posted by A. Sinan Unur on May 23, 2008, 6:48 pm
Please log in for more thread options

> In article
>
>>
>> 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.
>
> I'm not sure what you are asking. The FAQ are posted sequentially.
> Since the answers are to frequently asked questions, it's expected that
> the answer would show up at the same time as someone asks the
> question.

He is referring to the following thread:

http://groups.google.com/group/comp.lang.perl.misc/browse_thread/thread/e9ebb8db8db998f1/3e2cab2f34be8bcc
http://preview.tinyurl.com/4o9rea

If, instead of fully quoting the FAQ post, he had only included the
title of the question, his attempt at humor might have been more obvious.

At least, I am assuming that was an attempt at a joke.

Sinan

--
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/

Similar ThreadsPosted
FAQ 4.59 How do I sort a hash (optionally by value instead of key)? February 28, 2005, 12:03 am
FAQ 4.59 How do I sort a hash (optionally by value instead of key)? May 6, 2005, 5:03 am
FAQ 4.59 How do I sort a hash (optionally by value instead of key)? July 21, 2005, 10:03 pm
FAQ 4.59 How do I sort a hash (optionally by value instead of key)? October 11, 2005, 10:03 am
FAQ 4.59 How do I sort a hash (optionally by value instead of key)? April 21, 2006, 9:03 am
FAQ 4.59 How do I sort a hash (optionally by value instead of key)? June 8, 2006, 3:03 am
FAQ 4.59 How do I sort a hash (optionally by value instead of key)? July 10, 2006, 3:03 am
FAQ 4.59 How do I sort a hash (optionally by value instead of key)? August 4, 2006, 3:03 pm
FAQ 4.59 How do I sort a hash (optionally by value instead of key)? October 10, 2006, 3:03 pm
FAQ 4.59 How do I sort a hash (optionally by value instead of key)? December 26, 2006, 9:03 am

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap