我需要一个可以与排序一起使用的 Perl 比较函数。
每个键都是一个文本字符串,具有任意数量的子键,由分隔符(点、冒号、空格和斜杠)分隔。一些子键是数字的,需要按数字排序。密钥格式和子密钥数量各不相同。因此,比较必须处理一个键长于另一个键,并且必须处理子键在一个键中是数字但在另一个键中不是数字的情况(在这种情况下,文本比较适用于该子键)。
这行得通,但我敢打赌有更好的解决方案:
use warnings;
use strict;
use Scalar::Util qw[looks_like_number];
sub hier_cmp {
my $aa = $a;
my $bb = $b;
# convert all delims (. : / space) to the same delim
$aa =~ tr/.:\/ /::::/;
$bb =~ tr/.:\/ /::::/;
my @lista = split(":", $aa);
my @listb = split(":", $bb);
my $result;
for my $ix (0 .. min($#lista, $#listb)) {
if (exists($lista[$ix]) && exists($listb[$ix])) {
if ( looks_like_number($lista[$ix]) && looks_like_number($listb[$ix])) {
# compare numerically
$result = ($lista[$ix] <=> $listb[$ix]);
} else {
# compare as strings
$result = ($lista[$ix] cmp $listb[$ix]);
}
if ($result == 0) {
next;
}
return $result;
} elsif (exists($lista[$ix])) {
return 1;
} else {
return -1;
}
}
}
就我而言,可读性比速度更重要。这只是一个内部工具,列表很少有超过数百个元素。但是,任何学习东西的机会都是好的。
如您所见,我不是 perl 向导。即使对我的代码进行微不足道的改进也将不胜感激。
谢谢!