Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
奇数Perl';字典';排序行为_Perl_Tcl_Sorting - Fatal编程技术网

奇数Perl';字典';排序行为

奇数Perl';字典';排序行为,perl,tcl,sorting,Perl,Tcl,Sorting,我试图在Perl中实现Tcl字典排序,以便对一些文件进行排序。对于那些不了解Tcl的人,您可以让它按值对连续整数进行排序,详细内容如下: 总结如下: 给定的数组: qw( bigbang x10y x9y bigboy bigBoy x11y ) 按不区分大小写的字母排序,然后区分大小写作为平分符,然后按数字排序,除非它接受以下任何数字,并将整个内容解释为排序中的单个数字,因此上述结果如下: qw( bigbang bigBoy bigboy

我试图在Perl中实现Tcl字典排序,以便对一些文件进行排序。对于那些不了解Tcl的人,您可以让它按值对连续整数进行排序,详细内容如下:

总结如下: 给定的数组:

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;
}
sub-dict\u排序{
我的@unsorted=@;
我的@sorted=
地图$\u0->[0],
分类{
我的$i=0;
{
我的$A=$A->[1][$i];
my$B=$B->[1][$i];
已定义($A)|已定义($B)#如果两者都未定义,则停止
及(
定义($A)定义($B)#定义战胜未定义
或(
$A!~/\d/| |$B!~/\d/#$A或$B是非整数
?(lc$A cmp lc$B)#?严格小写
||($A cmp$B)#->平局断路器
:$A$B#::$A和$B是整数
或(
长度($A)长度($B)#如果数值比较结果相同,请检查长度以按前导零排序
)
)
或++$i&&redo#tie=>下一部分
);
}
}
映射[$\[split/(\d+)/]],@unsorted;
返回@sorted;
}

对于版本字符串,您的代码不会有不同的工作方式。只需按此顺序将
9.029.2
添加到列表中即可。如果希望02位于2之后,则必须在
$A==$B
时检查案例


更新:这意味着在
$A$B
之后添加
或length$A length$B

为了澄清,Tcl的字典排序将每个单词拆分为仅数字和非数字的交替字符串。数字序列按数字排序(当两个值相同时,有一点魔法处理前导零),非数字序列按不区分大小写的ASCII排序。当比较一个以数字开头的键和一个以非数字开头的键时,前导数字1会排在第一位。在任何人提出问题之前,这就很好地近似了用户认为文件名应该按什么排序。嗯,前导零可能会在这里造成问题,但是我很惊讶,我没有看到版本字符串和绝对路径都有相同的错误行为。在任何人提到之前,我个人知道Tcl字典排序给出的顺序不一定是“正确”的,但它用于另一段代码,我无法控制,也无法更改,但是必须进行模拟才能产生相同的结果:)提示:它不会改变顺序,因为在比较1.02和1.2时,它会检查02和2,并在尝试$A$B排序时将它们视为相同?嗯,更理想的做法是让它在$A$B返回相同的值时,再检查一次前导0的出现数,然后再继续进行剩余的sortThanks!我扩展了搜索,以在数字匹配时检查比较字符串的长度——因为如果一个字符串比另一个字符串长,但在数字比较中是相同的值,那么它必须有前导零——这似乎起到了作用:)我将编辑代码并加入工作函数,并将您的代码标记为正确的点。你能编辑你的答案并把我的功能放在那里,帮助任何遇到类似问题的人吗?