This works:
my %score = ( a => 1, b => 2);
@keys = sort {$score{$a} <=> $score{$b}} keys %score;
But how can I put the code inside {..} to a dedicated sub routine?
sub by_num {
$score{$a} <=> $score{$b}
}
@keys = sort by_num keys %score;
?
The main problem here is having a subroutine that has access to the hash. You either have to create one function per hash you want to sort:
#!/usr/bin/perl
use strict;
use warnings;
{
my %hash = (
a => 1,
b => 2,
c => 3,
);
sub sort_hash_a {
return $hash{$a} <=> $hash{$b};
}
for my $k (sort sort_hash_a keys %hash) {
print "$k\n";
}
}
{
my %hash = (
x => 1,
y => 2,
z => 3,
);
sub sort_hash_b {
return $hash{$a} <=> $hash{$b};
}
for my $k (sort sort_hash_b keys %hash) {
print "$k\n";
}
}
Or create a higher-order function that creates the functions for you:
#!/usr/bin/perl
use strict;
use warnings;
sub make_hash_sort {
my $hashref = shift;
return sub {
return $hashref->{$a} <=> $hashref->{$b};
};
}
my %hash = (
one => 1,
two => 2,
three => 3,
);
my $sub = make_hash_sort \%hash;
for my $k (sort $sub keys %hash) {
print "$k\n";
}
But all of that is, generally, wasted effort for both the programmer and the computer. The block syntax is faster and easier to use in almost all cases. The only exceptions would be complicated sorts or highly repetitive code.
A hash produces a list of key/value pairs in list context; you're then using the values as keys, and there is no e.g. $score{90}. Use keys %score to get just the keys.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With