TCL:根据字符串的一部分对字符串列表进行排序

时间:2013-11-20 11:25:07

标签: list sorting tcl

我不是TCL的专家,但不幸的是必须处理它。我正在尝试这样做:我有一个字符串列表:例如“test2”test3“test1”。我想在“测试”之后使用数字对列表进行排序。我已经阅读了所有的lsort命令选项,但我认为没有简单的方法,因为tcl没有(WHY ???)将字符串视为数组,例如python。我怎样才能做到这一点 ?谢谢大家。

3 个答案:

答案 0 :(得分:2)

lsort命令有一个-dictionary选项,它完全正确 你想要什么:

% set lis {test1 test10 test20 test15 test3}
test1 test10 test20 test15 test3
% puts [lsort -dictionary $lis]
test1 test3 test10 test15 test20

答案 1 :(得分:1)

简单的答案是:

set yourlist {test2 test3 test1}
puts [lsort $yourlist]

但如果您有数字>这将失败10:

set yourlist {test2 test3 test1 test11}
puts [lsort $yourlist]

所以你可能需要自己比较一下:

proc mycompare {arg1 arg2} {
   if {[regexp {test(\d+)} $arg1 -> n1] && [regexp {test(\d+)} $arg2 -> n2]} {
       return [expr {$n1 - $n2}]
   }
   return [string compare $arg1 $arg2]
}

set yourlist {test2 test3 test1 test11}
puts [lsort -command mycompare $yourlist]

实际上,Tcl可以将字符串视为字节数组,因此语句的问题为

  

tcl没有(为什么???)将字符串视为数组

是你对“阵列”的定义。在Tcl中,我们通常使用列表作为值序列,如果要获取所有字符的列表,请使用split $yourstring {}

答案 2 :(得分:1)

我使用Schwarzian变换方法

% set l {test1 test10 test20 test3}
test1 test10 test20 test3
% foreach elem $l {lappend new [list $elem [regexp -inline {\d+} $elem]]}    
% set new
{test1 1} {test10 10} {test20 20} {test3 3}
% foreach pair [lsort -index 1 -integer $new] {lappend result [lindex $pair 0]}
% puts $result
test1 test3 test10 test20

对于Tcl 8.6

set result [
    lmap e [
        lsort -integer -index 1 [
            lmap e $l  {list $e [regexp -inline {\d+} $e]}
        ]
    ] {lindex $e 0}
]
test1 test3 test10 test20

离开方式偏离主题,这与perl

进行比较
my @l = qw/ test1 test10 test20 test3 /;
my @result = map {$_->[0]}
             sort {$a->[1] <=> $b->[1]}
             map {m/(\d+)/ and [$_, $1]}
             @l;