简体   繁体   中英

Perl Sort a hash by value in descending order and then key in ascending order

Suppose I have a hash like

%hash = 
{
    husky => 2
    alaska => 2
    akita => 3
    brand =>1
}

How can I sort it by descending value(number), and ascending key(alphabet)? The desired result should be:

{
    akita =>3
    alaska =>2
    husky =>2
    brand=>1
}

A hash in Perl is not ordered nor it can be ordered. This is because the hash algorithm will spread the keys at random. A hash is defined like this:

my %hash = (
  key1 => value1,
  key2 => value2,
);

That is, it is defined with a list of value pairs key => value . If you want a collection of ordered items, you need to use a list. It is defined like:

my @list = ( 1, 2, 3 );

You may define a list of hash refs (closer to what you want) like this:

my @list = (
  { key1 => value1 },
  { key2 => value2 },
);

A hash ref is a reference to a hash, and it is defined with { and } .

So solving your problem, we have:

use Data::Dumper;

my %hash = (
  husky => 2,
  alaska => 2,
  akita => 3,
  brand =>1,
);

my @list = map { { $_ => $hash{$_} } } 
           sort { $hash{$b} <=> $hash{$a} or $a cmp $b }
           keys %hash;

print Dumper(@list);

keys %hash will give you a list of the keys in the hash. sort will sort elements in a list. As we want a special ordering, we provide the body of the sorting bit using the operators <=> to compare numbers and cmp to compare strings. Each returns -1 if the left side is less than the right side; 0 if they are the same and 1 if the left side is more than the right side. The or will enter the second comparison if the first is 0 .

Finally, map will transform the list of keys (ordered) into a list of hash refs.

Dumper is a function that creates a human readable text representation of any Perl data structure.

The final output is:

$VAR1 = {
          'akita' => 3
        };
$VAR2 = {
          'alaska' => 2
        };
$VAR3 = {
          'husky' => 2
        };
$VAR4 = {
          'brand' => 1
        };

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