Reputation: 375
use Data::Dumper;
sub byage {
$age{$a} <=> $age{$b}; # presuming numeric
}
my @class = ( { student => "student1", age => 33, },
{ student => "student2", age => 66, },
{ student => "student3", age => 44, }, );
my @sortedclass = sort byage @class;
print Dumper(@class);
print Dumper(@sortedclass);
I am trying to follow perldoc Sort examples. I want to sort a list of hashes, based on at least in perldoc example, value of age key. Not certain what I am doing wrong. The above does not appear to sort.
Upvotes: 3
Views: 237
Reputation: 69244
From a comment:
What data structure are perldocs referencing with regards to $age{b}
I think you've been looking at this entry in the Perl FAQ - How do I sort a hash (optionally by value instead of key)? It contains this example:
my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash;
The data structure the sort expression is referring to is the hash called %hash
.
When you borrowed that example for your own code, you changed it to this:
sub byage {
$age{$a} <=> $age{$b}; # presuming numeric
}
This is looking for a hash called %age
. But nowhere in your code is there a hash called %hash
. You have an array called @class
.
There are a few misunderstandings here, but I think the most important one is this. The FAQ you were looking at is about sorting a hash[*] ("How do I sort a hash...?") but you want to sort a list[**] ("Sorting list of ..."). List (or arrays) and hashes are rather different data structures, so it's going to be unhelpful trying to use a sorting technique meant for a hash when you're trying to sort an array.
The sort()
function sorts a list. You give it one list and it returns another. In the FAQ example, the input list is the keys of a hash (produced with keys %hash
) and the output list is those same keys sorted in a different order. In your actual problem, the input is an array of hash references and the output is a list of those hash references in a different order.
When you write a sort expression (or, in your case, a sort subroutine), you get two elements of the input list in $a
and $b
and you return a value indicating how those two values should be sorted. In the FAQ example, $a
and $b
will be keys and you can use those keys to look into the hash ($hash{$a}
and $hash{$b}
) and get the associated values. In your problem, $a
and $b
will be two of the hash references from your input array. You can look up the "age" key in reach of those ($a->{age}
and $b->{age}
) to get the values you want to compare.
As others have pointed out. Adding use strict
and use warnings
to your code is always a good idea. Fixing the problems they show you is an even better one.
[*] Pedantically, you can't sort a hash. What the FAQ code is actually doing is producing a sorted list of hash keys.
[**] Although you actually have an array, not a list.
Upvotes: 1
Reputation: 93636
The first thing you should be doing is putting use warnings; use strict;
at the top of your code so you can get the warning that there is no hash %age
.
What you want is to compare the age
values in each of $a
and $b
.
sub byage {
$a->{age} <=> $b->{age}; # presuming numeric
}
my @class = (
{ student => "student1", age => 33, },
{ student => "student2", age => 66, },
{ student => "student3", age => 44, },
);
my @sortedclass = sort byage @class;
Upvotes: 6