2013-03-18 65 views
0

我的名单是:如何排序列表,同时优先考虑数字之前的字母表?

set list {23 12 5 20 one two three four} 

预期输出是递增的顺序,不同的是,字母需要在开始的时候放:

four one three two 12 20 23 5 

我试过如下:

# sorting the list in increasing order: 
lsort -increasing $list 
-> 12 20 23 5 four one three two 
# Here i get the result with numbers first as the ascii value of numbers are higher than alphabets. 

 

lsort -decreasing $list 
# -> two three one four 5 23 20 12 
+0

您是否也想作为数字排序,而不是作为字符串的数字吗? (即12之前5) – 2013-03-18 13:02:07

回答

2

我建议拧一个比较:

proc compareItm {a b} { 
    set aIsInt [string is integer $a] 
    set bIsInt [string is integer $b] 

    if {$aIsInt == $bIsInt} { 
     # both are either integers or both are not integers - default compare 
     # but force string compare 
     return [string compare $a $b] 
     # if you want 5 before 12, comment the line above and uncomment the following line 
     # return [expr {$a < $b ? -1 : $a > $b ? 1 : 0}] 
    } else { 
     return [expr {$aIsInt - $bIsInt}] 
    } 
} 

而且随着-command选项lsort使用它:

lsort -command compareItm 
+0

@glenn:排序数字也会有帮助... – deva 2013-03-18 16:20:24

0

一个最简单的方法是产生整理键和排序的:

lmap pair [lsort -index 1 [lmap item $list { 
    list $item [expr {[string is integer $item] ? "Num:$item" : "Let:$item"}] 
}]] {lindex $pair 0} 

如果您使用的是Tcl 8.5或8.4(缺乏lmap),你这样做有一个更啰嗦版:

set temp {} 
foreach item $list { 
    lappend temp [list $item [expr { 
     [string is integer $item] ? "Num:$item" : "Let:$item" 
    }]] 
} 
set result {} 
foreach pair [lsort -index 1 $temp] { 
    lappend result [lindex $pair 0] 
} 
相关问题