【问题标题】:order two list with the same indices订购两个具有相同索引的列表
【发布时间】:2018-10-26 15:57:12
【问题描述】:

我是 tcl 的新手。我需要对值列表进行排序并保存索引。 我有 2 个列表,我想对 listA 进行排序,但随后我想对 listB 进行排序,并保留来自 listA 的索引。

例如:

set listA {5 6 7 3 4 7 8 9}
set listB {0 1 2 3 4 5 6 7}

set sort_listA [lsort $listA]

现在sort_listA 将是3 4 5 6 7 7 8 9

我想对listB 列表进行排序,保持与sort_listA 相同的索引,例如:

3 4 0 1 2 5 6 7

换句话说,我需要使用listA 的排序对两个列表进行排序。 谁能帮帮我?

【问题讨论】:

    标签: sorting tcl tclsh


    【解决方案1】:

    这正是lsort 具有-indices 选项的任务类型(需要8.5 或更高版本)。它不是排序值列表,而是将索引列表返回到原始列表中,按照您检索它们以获得排序列表的顺序,这非常适合您的任务。这个交互式会话(在 Tcl 8.6 中,所以我有 lmap)是指示性的:

    % set listA {5 6 7 3 4 7 8 9}
    5 6 7 3 4 7 8 9
    % set listB {0 1 2 3 4 5 6 7}
    0 1 2 3 4 5 6 7
    % set idxs [lsort -indices $listA]
    3 4 0 1 2 5 6 7
    % lmap i $idxs {lindex $listA $i}
    3 4 5 6 7 7 8 9
    % lmap i $idxs {lindex $listB $i}
    3 4 0 1 2 5 6 7
    

    如果您仍在使用 8.5,则可以使用 foreach 进行重新映射;通过程序更容易:

    proc mapindices {indexlist valuelist} {
        set result {}
        foreach i $indexlist {
            lappend result [lindex $valuelist $i]
        }
        return $result
    }
    set listA {5 6 7 3 4 7 8 9}
    set listB {0 1 2 3 4 5 6 7}
    puts [mapindices [lsort -indices $listA] $listB]
    

    现在,在 8.4(不再支持!)中没有索引选项,因此您需要做更多的工作。

    proc lsortIndices {list} {
        # Pair each value up with its index
        set zipped {}
        set idx -1
        foreach val $list {
            lappend zipped [list [incr idx] $val]
        }
    
        # Do the sorting by the value of the pair
        set sorted [lsort -index 1 $zipped]
    
        # Unpack the indices from the pairs to get the result
        set result {}
        foreach pair $sorted {
            lappend result [lindex $pair 0]
        }
        return $result
    }
    

    但是,此时您可能只需将两个列表压缩在一起并更直接地工作:

    set zipped {}
    foreach valA $listA valB $listB {
        lappend zipped [list $valA $valB]
    }
    
    set sorted [lsort -index 0 $zipped]
    
    set listAsorted {}
    set listBsorted {}
    foreach pair $sorted {
        lappend listAsorted [lindex $pair 0]
        lappend listBsorted [lindex $pair 1]
    }
    

    使用旧版本的 Tcl 比 8.4 需要您使用 -command 选项,这真的很慢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-08
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2020-08-20
      • 2020-05-19
      • 1970-01-01
      相关资源
      最近更新 更多