I have a Perl function:
my %d;
$d{"aaaa"}->{t1} = "9:49";
$d{"bbbb"}->{t1} = "9:30";
foreach my $k (sort { ($d{$a}->{t1}) <=> ($d{$b}->{t1}) } keys %d)
{
print "$k: $d{$k}->{t1}\n";
}
I want to sort by t1, so 9:30 before 9:49 and I want to get the result:
bbbb: 9:30
aaaa: 9:49
but the result is not suitable.
It seems like the result is random?
C:\tmp>a.pl
bbbb: 9:30
aaaa: 9:49
C:\tmp>a.pl
bbbb: 9:30
aaaa: 9:49
C:\tmp>a.pl
bbbb: 9:30
aaaa: 9:49
C:\tmp>a.pl
aaaa: 9:49
bbbb: 9:30
C:\tmp>a.pl
bbbb: 9:30
aaaa: 9:49
C:\tmp>a.pl
bbbb: 9:30
aaaa: 9:49
C:\tmp>a.pl
bbbb: 9:30
aaaa: 9:49
C:\tmp>a.pl
aaaa: 9:49
bbbb: 9:30
You need to use cmp
instead of <=>
since you are comparing strings. The comments are correct and we need to take into consideration 10+ hours. You need to use sprintf to add leading zero when hours are less than 10 to have strings sorted correctly.
foreach my $k (sort { sprintf("%05s", ($d{$a}->{t1})) cmp sprintf("%05s", ($d{$b}->{t1})) } keys %d) {
<=>
is for comparing numbers, but your times have a colon, which makes them strings instead of numbers. One workaround is to just remove the colon, so that <=>
can operate on them in number context.
use v5.10;
say "$_: $d{$_}->{t1}" for sort { $d{$a}->{t1} =~ s/://r <=> $d{$b}->{t1} =~ s/://r } keys %d;
The r
modifier on the substitution means return the new value without altering the old value.
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.