Hi I have a data structure which is of the following form:
$data = {                                                                                           
    'a' => { key1 => 2, key2 => 1 },                                                                   
    'b' => { key1 => 1, key2 => 2 },                                                                   
    'c' => { key1 => 1, key2 => 1 },                                                                   
    'd' => { key1 => 3, key2 => 2 },                                                                   
    'e' => { key1 => 3, key2 => 1 },                                                                   
    'f' => { key1 => 1, key2 => 2 },                                                                   
};
what I want to be able to do is loop through this data structure in ascending order of key2, descending order of key1, and then ascending order of the hash key, e.g:
e
a
c
d
b
f
how can I achieve this in perl? I know that I can sort the hash by key using sort keys %$data, but how can I sort by multiple values and keys?
A similar question has been asked before and can be found here: Sorting an Array of Hash by multiple keys Perl
Basically, Perl has two operators for sorting, <=> and cmp which return -1, 0 or 1, depending on if the left hand side is less than, equal to, or greater than the right hand side. <=> is used for numerical comparison, and cmp is used for stringwise comparison. More detail about their use can be found here: Equality Operators. 
These operators can be used with Perl's sort function and in conjuction with the or operator can be used to achieve the result you're after:
#!/usr/bin/perl
use strict;
use warnings;
my $data = {
    'a' => { key1 => 2, key2 => 1 },
    'b' => { key1 => 1, key2 => 2 },
    'c' => { key1 => 1, key2 => 1 },
    'd' => { key1 => 3, key2 => 2 },
    'e' => { key1 => 3, key2 => 1 },
    'f' => { key1 => 1, key2 => 2 },
};
my @sorted = sort {
        $data->{$a}->{key2} <=> $data->{$b}->{key2} or
        $data->{$b}->{key1} <=> $data->{$a}->{key1} or
        $a cmp $b
    } keys %{$data};
for my $key (@sorted){
    print "$key\n";
}
Since <=> and cmp return 0 (false) for equality, it means we can chain equality checks together with or or ||. 
In the example above we $a and $b to refer to a key of the $data hashref at a particular iteration of the sort. Using these keys we can access particular values of the hash, e.g. $data->{$a}->{key2}. By putting $a before $b it will cause the sort to be in ascending order, and putting $b before $a will cause the sort to be in descending order. 
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