如何在数字前优先输入字母表时对列表进行排序?

时间:2013-03-18 12:14:22

标签: tcl

我的清单是:

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

2 个答案:

答案 0 :(得分: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的{​​{1}}选项一起使用:

lsort

答案 1 :(得分: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]
}