4
votes

I have a hash of arrays that looks like this:

{ $key, [$val1, $val2] }

I'm trying to numerically sort by the second value of the array and print out the entire hash. I've taken a look at the Schwartzian Transform posts, but I haven't seen one that does exactly what I want. I'm also very confused by the syntax and how to map the sorted values back into the original {$key, [$val1, $val2] } form. Any help would be appreciated!

2
1 in 4, surely? (Not that that's much better!)Dave Cross
@davorg 5 questions, 1 accepted. Not sure how SO calculates this rate, it sure looks weird.TLP
Schwartzian transform deals with sorting on computed values. You want to compute them once for each element not 2 * nlogn times. You already have the value you want to sort on computed $hash->{ $key }[1]. You do not need a Schwartzian transform.Axeman
@TLP there is a certain delay before new questions are used in that calculation.Brad Gilbert
Don't try to use a Schwartzian Transform until you learn more about Perl in general.Brad Gilbert

2 Answers

14
votes

Not quite sure what you are referring to, but this is how you implement a sort routine on an array value, inside a hash:

my %hash = ( 'key1' => [ 1, 2 ], 'key2' => [ 2, 3 ] );

for my $key ( sort { $hash{$a}[1] <=> $hash{$b}[1] } keys %hash ) {
    print "$key => '", join(", ", @{$hash{$key}}), "'\n";
}
7
votes

I you really want to use a Schwartzian-Transform, here is a way to do it:

#!/usr/bin/perl
use Data::Dump qw(dump);

my %hash = (k1 => [1, 2], k2 => [24, 5], k3 => [5, 1]);
foreach(
        sort { $a->[1] <=> $b->[1] }
        map { [$_, $hash{$_}->[1] ] } keys %hash) {
    say $_->[0],' => ',dump$hash{$_->[0]};
}

output:

k3 => [5, 1]
k1 => [1, 2]
k2 => [24, 5]

NB:

I just give this answer as an example of Schwartzian Transform

But as said in comment, there's no need of it in the case explained in the question, ST is cost saving when there are some computation for each element of array before sorting. For the question asked, there's no computation to be done, so don't use ST here.