Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

How do you sort a hash of array refs?

by el-moe (Scribe)
on Nov 16, 2000 at 04:29 UTC ( [id://41921]=perlquestion: print w/replies, xml ) Need Help??

el-moe has asked for the wisdom of the Perl Monks concerning the following question:

I have a hash of array refs

my %hash = ( TYPE => ["hole", "hole", "chain", "slot"], SIZE => [126, 93, 96, 130], STEP => ["pcb", "pcb", "array", "panel"], COMP => ["none", "none", "right", "left"], );

I need to sort the $hash{SIZE} array and have all the other arrays sort along with it.

I looked at a lot of documentation and found sorts of many types but none match my problem. I was thinking the Schwartzian Transform might work but I'm not sure how to get from the example to a working ST I can use...

Thanks in advance for all your help!!

Prost,
Moe

Replies are listed 'Best First'.
Re (tilly) 1: How do you sort a hash of array refs?
by tilly (Archbishop) on Nov 16, 2000 at 05:09 UTC
    Well normally for something like this I would arrange to have an array of hash refs:
    my @array = ( {TYPE => "hole", SIZE => 126, STEP => "pcb", COMP => "none"}, {TYPE => "hole", SIZE => 93, STEP => "pcb", COMP => "none"}, {TYPE => "chain", SIZE => 96, STEP => "array", COMP => "right"}, {TYPE => "slot", SIZE => 130, STEP => "panel", COMP => "left"}, );
    and now sorting it is as easy as:
    @sorted = sort {$a->{SIZE} <=> $b->{SIZE}} @array;
    This kind of design is better for a number of reasons. But still in your case you have an unfriendly data structure for the operation. Well here is a way to do this:
    my @indices = sort {$hash{SIZE}[$a] <=> $hash{SIZE}[$b]} 0..$#{$hash{S +IZE}}; foreach my $key (keys %hash) { @{$hash{$key}} = @{$hash{$key}}[@indices]; # Slice }
    But honest, reversing the structure of your data structure now is advised if at all possible.
Re: How do you sort a hash of array refs?
by runrig (Abbot) on Nov 16, 2000 at 04:33 UTC
    Try this:
    my @sorted = sort { $hash{SIZE}[$a] <=> $hash{SIZE}[$b] } 0..$#{$hash{ +SIZE}}; $hash{$_} = [ @{$hash{$_}}[@sorted] ] for keys %hash;
      The original author may want to have a look at The indirect Sort. This is the technique that runrig demonstrated. The page linked above shows the same technique with a simpler example and a little more explanation.

      Thanks runrig. I see what you're doing now. I tested it on my system and it's going to work.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (8)
As of 2024-04-19 12:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found