在tcl中排序2D列表

时间:2014-08-16 08:28:19

标签: list indexing tcl sublist

虽然我在lsort中读了很多选项来做这件事,但在我的情况下它没有用。 我有一个浮动数字列表,如下面

{898.465 348.700} {898.465 1511.400} {477.130 348.700} {898.465 730.200} {477.130 1511.400} {898.465 1121.400} {477.130 730.200} {477.130 1121.400}

我想用第二个索引对它进行排序,这样我就可以获得第二个索引的最小值和最大值。我尝试了下面的东西并得到了很少的输出,但没有任何帮助。

lsort -index end-1  -decreasing  `$bbox_upper`
{477.130 348.700} {477.130 1511.400} {477.130 730.200} {477.130 1121.400} {898.465 348.700} {898.465 1511.400} {898.465 730.200} {898.465 1121.400}

lsort -index 1 -real $bbox_upper
{898.465 1121.400} {477.130 1121.400} {898.465 1511.400} {477.130 1511.400} {898.465 348.700} {477.130 348.700} {898.465 730.200} {477.130 730.200}

如果您在上面的输出中看到,第二个索引1511.400是最大的,所以它应该出现在第一个子列表中,但它不会出现

你能帮忙吗?

1 个答案:

答案 0 :(得分:2)

您使用的是哪种确切版本的Tcl(使用info patchlevel查找)?当我使用8.6.1进行尝试时,只要我使用我需要的所有选项(我也希望它适用于任何基于8.5或基于8.4的Tcl),它都能正常工作:

% info patchlevel
8.6.1
% lsort -index 1 -decreasing -real $bbox_upper
{898.465 1511.400} {477.130 1511.400} {898.465 1121.400} {477.130 1121.400} {898.465 730.200} {477.130 730.200} {898.465 348.700} {477.130 348.700}

我不会使用索引end-1,除非你的意思是“最后一个”。对于数字排序,-real选项是正确的; -dictionary也可能有用,但是它使用了一种非常不同的基于字符串的算法(在文件选择器对话框中的文件名列表中向用户显示的值具有良好的结果),并且对于真正的浮点数不会有效数据


如果您需要更复杂的排序,例如在第二个值相同时使用每对的第一个值作为抢七,您可以选择几个选项。

通常通过对数据进行两次排序来最好地处理辅助密钥。这不是最有效的技术,但很容易做到正确,Tcl的lsort使用稳定的排序算法。

lsort -index 1 -decreasing -real [lsort -index 0 -decreasing -real $bbox_upper]

或者,您可以使用-command选项将订购决策委托给您提供的某些代码:

proc sorter {aValue bValue} {
    foreach {ax ay} $aValue break
    foreach {bx by} $bValue break
    set diff [expr {$ay - $by}]
    if {$diff == 0} {
        set diff [expr {$ax - $bx}]
    }
    return [expr {$diff < 0 ? 1 : $diff > 0 ? -1 : 0}]
}
lsort -command sorter $bbox_upper

从8.5开始,您可以在不引入帮助程序的情况下执行此操作:

lsort -command {apply {{aValue bValue} {
    lassign $aValue ax ay
    lassign $bValue bx by
    set diff [expr {$ay - $by}]
    if {$diff == 0} {
        set diff [expr {$ax - $bx}]
    }
    return [expr {$diff < 0 ? 1 : $diff > 0 ? -1 : 0}]
}}} $bbox_upper

你被告知使用程序会更快,甚至更快(至少在这种情况下)是一种双重排序。