Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

How do I sort a Hash of Hashes?

by greywolf (Priest)
on Jan 10, 2004 at 00:13 UTC ( [id://320255]=perlquestion: print w/replies, xml ) Need Help??

greywolf has asked for the wisdom of the Perl Monks concerning the following question: (sorting)

I have a hash of hashes that looks like this:

my %products ( 1 => { name => "Floor Wax", wholesale => "50.00", retail => "75.00", }, 2 => { name => "Paper Towel", wholesale => "20.00", retail => "40.00", }, 3 => { name => "Hand Soap", wholesale => "30.00", retail => "65.00", }, );
I can sort and print this hash by the keys using the following:
foreach my $key (sort {$a <=> $b} keys %products) { print "<br>K|$key| N|$products{$key}{name}| W|$products{$key}{whol +esale}| R|$products{$key}{retail}|"; }
How would I sort %products by the name or wholesale of each product? I have tried many variations of this to no avail.
foreach my $key (sort {$products{retail}{$a} <=> $products{retail}{$b} + keys %products) { print "<br>K|$key| N|$products{$key}{name}| W|$products{$key}{whol +esale}| R|$products{$key}{retail}|"; }
I have read the hash of hashes section of the camel many times. Am I missing something obvious here or should I be transforming this into another data structure before printing.

mr greywolf

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: How do I sort a Hash of Hashes?
by neuroball (Pilgrim) on Jan 10, 2004 at 02:34 UTC

    You have to rewrite the code so, that it sorts using the string comparitor (cmp) and you have to dereference the Hash of Hashes with an arrow operator.

    sort { $products{$a}->{"name"} cmp $products{$b}->{"name"} }
      You have to rewrite the code so, that it sorts using the string comparitor (cmp) and you have to dereference the Hash of Hashes with an arrow operator.
      The extra arrow isn't needed anymore. This changed sometime at or before 5.6.1.
Re: How do I sort a Hash of Hashes?
by NetWallah (Canon) on Jan 10, 2004 at 05:55 UTC
    The most straightforward answer is as neuroball has stated:

    sort { $products{$a}->{"name"} cmp $products{$b}->{"name"} }

    However....

    This has some performance implications in that the hash dereference and comparison get performed many more times than necessary, as sort calls the compare routine each time it compares. This is a lot more then the number of elements to be compared.

    If the number of elements is large, and you care about performance, you should look into the Schwartzian Transform algorithm, which perfoms the de-reference the minimum number of times.

    Editor's Note: See, however, this discussion, which reveals that hash dereferences are not usually expensive enough to warrant the power and majesty of a Schwartzian transform...

Re: How do I sort a Hash of Hashes?
by injunjoel (Priest) on Oct 19, 2005 at 20:21 UTC
    Greetings all,
    Just another suggestion. I would turn %products into an array and then use the Schwartzian Transform to do the sorting.
    untested suggestion
    my @products ( { name => "Floor Wax", wholesale => "50.00", retail => "75.00", }, { name => "Paper Towel", wholesale => "20.00", retail => "40.00", }, { name => "Hand Soap", wholesale => "30.00", retail => "65.00", } ); my @sorted_by_name = map{$_->[1]} sort {$a->[0] cmp $b->[0]} map{[$_->{name},$_]} @products my @sorted_by_wholesale = map{$_->[1]} sort {$a->[0] <=> $b->[0]} map{[$_->{wholesale},$_]} @products
    Hope that helps,
    -InjunJoel
Re: How do I sort a Hash of Hashes?
by neuroball (Pilgrim) on Jan 10, 2004 at 02:23 UTC

    You have to rewrite the sort to fit the category you want to sort for:

    sort { $products{$a}->{"name"} <=> $products{$b}->{"name"} }

    code is NOT tested

    /oliver/

Re: How do I sort a Hash of Hashes?
by Anonymous Monk on Jun 22, 2004 at 17:22 UTC
    i can redeclare $a and $b :P

    Originally posted as a Categorized Answer.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://320255]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2024-03-19 04:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found