2013-11-20 91 views
0

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

+0

它通常没有必要处理字符串作为字符序列(事实上的Tcl认为字符串是更基础的数据类型)。当有必要时,'split $ theString {}'会给出一个字符列表。 –

回答

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没有(为什么???)认为字符串作为数组

是你的 “阵列” 的definiton。在Tcl中我们通常使用名单值的序列,如果你想获得的所有字符的列表中使用split $yourstring {}

+0

谢谢你的回答!我抱怨我的声明“tcl没有(WHY ???)将字符串视为数组”意思是说,如果设置a =“abcde”,简单地能够解决(2)会更容易,但这是抱怨一个喜欢python的懒惰的人;) – user3012827

+0

好吧,要从列表中获得第n个元素,您使用'lindex $ mylist $ n',对于使用'string index $ mystring $ n'的字符串。如果Tcl API将被重新设计,那么所有的l *命令将被重命名为'list ...',但是已经有一个'list'命令,这是非常重要的。 –

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; 
+0

您可以使用8.6的'lmap'来简化... –

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

仅当_all_的前缀是'test' ... –

+0

非常感谢你,这符合我的意图,我的教程没有涵盖所有的lsort选项:) – user3012827

相关问题