我有一个表示时间值的字符串列表,即1us,100ps,10s,7fs(微秒,皮秒,秒,飞秒等)。 我需要按升序对列表进行排序。为此,我编写了一个比较例程,当给出两个字符串时,将每个字符串转换为相应的数值并进行比较。但是,列表没有正确排序。经过多次调试后,我感到很茫然。这是我的代码:
#!/usr/bin/perl
use warnings;
use strict;
my %scales = ('fs'=>1e-15,'ps'=>1e-12,'ns'=>1e-9,'us'=>1e-6,'ms'=>1e-3,'s'=>1);
my @times = ('1s','7ns','100ps','500ms','9us');
my @stimes = sort bytime @times;
sub bytime {
my $op1 = $a;
my $op2 = $b;
$op1 =~ /\b(\d+)([munpf]*s)\b/;
my $v1 = $1 * $scales{$2};
$op2 =~ /\b(\d+)([munpf]*s)\b/;
my $v2 = $1 * $scales{$2};
return $v1 > $v2;
}
print "@times"."\n"."@stimes"."\n";
我得到的结果是:
1s 7ns 100ps 500ms 9us
100ps 7ns 500ms 1s 9us
这显然是错误的,即使进行了一些排序。 发生了什么事?
答案 0 :(得分:7)
您的错误就行了
return $v1 > $v2;
如果$v1
大于$v2
,则返回1(true),在所有其他情况下,0
(false)将返回
您希望改为使用数值比较运算符<=>
:
return $v1 <=> $v2;
将返回1,0或-1,具体取决于比较结果,并允许排序正常工作。 (如果您处理字符串而不是数字,则运算符为cmp
。)
完整的工作代码:
#!/usr/bin/perl
use warnings;
use strict;
my %scales = ('fs'=>1e-15,'ps'=>1e-12,'ns'=>1e-9,'us'=>1e-6,'ms'=>1e-3,'s'=>1);
my @times = ('1s','7ns','100ps','500ms','9us');
my @stimes = sort bytime @times;
sub bytime {
my $op1 = $a;
my $op2 = $b;
$op1 =~ /\b(\d+)([munpf]*s)\b/;
my $v1 = $1 * $scales{$2};
$op2 =~ /\b(\d+)([munpf]*s)\b/;
my $v2 = $1 * $scales{$2};
return $v1 <=> $v2;
}
print "@times"."\n"."@stimes"."\n";
输出:
1s 7ns 100ps 500ms 9us
100ps 7ns 9us 500ms 1s