简体   繁体   中英

Sorting list of hashes in Perl with sort

   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.

The first thing you should be doing is putting use warnings; use strict; 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;

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM