Perl排序哈希,如何按$ hash {$ key}-> {secondkey}排序

时间:2018-11-08 16:39:59

标签: perl

我有一个Perl函数:

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";
}

我想按t1排序,所以9:49之前的9:30我想得到结果:

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
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

enter image description here

2 个答案:

答案 0 :(得分:2)

由于要比较字符串,因此需要使用cmp而不是<=>。 这些评论是正确的,我们需要考虑10个多小时。 您需要使用sprintf在小时数少于10时添加前导零,以使字符串正确排序。

foreach my $k (sort { sprintf("%05s", ($d{$a}->{t1})) cmp sprintf("%05s", ($d{$b}->{t1})) } keys %d) {

答案 1 :(得分:1)

<=>用于比较数字,但是您的时间带有一个冒号,该冒号使它们成为字符串而不是数字。一种解决方法是仅删除冒号,以便<=>可以在数字上下文中对其进行运算。

use v5.10;

say "$_: $d{$_}->{t1}" for sort { $d{$a}->{t1} =~ s/://r <=> $d{$b}->{t1} =~ s/://r } keys %d;

替换中的r修饰符意味着返回新值而不更改旧值。