2013-03-18 64 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] 
} 
相關問題