我正在尝试在Perl中实现Tcl字典排序,以便订购一些文件。对于那些不了解Tcl的人,你可以按照它们的值对连续整数进行排序,详情如下:
http://www.perlmonks.org/index.pl?node_id=160157
总结一下: 给定数组:
qw(
bigbang
x10y
x9y
bigboy
bigBoy
x11y
)
按不区分大小写的字母排序,然后区分大小写作为打破平局,然后按数字排序,除了它接受任何后续数字并将整个事物解释为排序中的单个数字,因此上述内容如下所示:
qw(
bigbang
bigBoy
bigboy
x9y
x10y
x11y
)
x9y出现在x10y和x11y之上,而在标准的ASCII排序中,x10y和x11y将高于x9y,因为1出现在9之前。
我试图在该链接中实现Juerd的示例作为函数,但在我的情况下,当我有一个版本号列表时,排序完全模仿Tcl字典排序,如下所示:
qw{ 1 1.0 1.01 1.2 1.02 1.0003 1.102 1.103 1.203 102a 102b 103a 103b 123 };
但是当绝对路径用于文件时,排序会混乱。
我在下面发布了一个示例脚本。如果有人能够理解为什么功能出错了,或者你可以建议一个更现代的替代方案(因为我工作的例子是10年前发布的:P),我将不胜感激。
如果您想查看Tcl字典排序,请查看以下链接:
提前致谢!
编辑: - 感谢choroba
引导我找到解决方案!工作职能如下:
sub dict_sort {
my @unsorted = @_;
my @sorted =
map $_->[0],
sort {
my $i = 0;
{
my $A = $a->[1][$i];
my $B = $b->[1][$i];
defined($A) || defined($B) # Stop if both undef
and (
defined($A) <=> defined($B) # Defined wins over undef
or (
$A !~ /\d/ || $B !~ /\d/ # $A or $B is non-integer
? (lc $A cmp lc $B) # ?? Stringy lowercase
|| ( $A cmp $B) # -> Tie breaker
: $A <=> $B # :: $A and $B are integers
or (
length($A) <=> length($B) # If numeric comparison returns the same, check length to sort by leading zeroes
)
)
or ++$i && redo # tie => next part
);
}
}
map [ $_, [ split /(\d+)/ ] ], @unsorted;
return @sorted;
}
答案 0 :(得分:3)
您的代码对版本字符串的工作方式不同。只需按此顺序将<{1}}添加到列表 即可。如果你希望02在2之后来,你必须在9.02 9.2
时检查案例。
更新:这意味着在$A == $B
之后添加or length $A <=> length $B
。