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.