在 tcl 列表中按名称分组



>我有这样的列表

set a {CSCvi6:sunil CSCvi7:sunil CSCvi8:parames CSCvi87:sunil CSCvi878:sunil CSCvi89:arun CSCvi95:sunil CSCvj3:sunil CSCvj1:arun}

如何按名称显示列表分组,例如

sunil:CSCvi6 CSCvi7 CSCvi87 CSCvi878 CSCvi95 CSCvj3
arun:CSCvi89 CSCvj1
parames :CSCvi8

我在 tcl 中搜索了groupby,但不幸的是我没有找到与此相关的东西。 帮我做那

件事

您需要遍历列表并使用字典(或数组(来收集组:

set a {CSCvi6:sunil CSCvi7:sunil CSCvi8:parames CSCvi87:sunil CSCvi878:sunil CSCvi89:arun CSCvi95:sunil CSCvj3:sunil CSCvj1:arun}
set map [dict create]
foreach pair $a {
    lassign [split $pair :] value name
    dict lappend map $name $value
}
dict for {name values} $map {puts "$name: $values"}
sunil: CSCvi6 CSCvi7 CSCvi87 CSCvi878 CSCvi95 CSCvj3
parames: CSCvi8
arun: CSCvi89 CSCvj1

仔细观察,我们可以实现一个groupby过程,该过程获取列表并创建字典

proc groupby {varname lst grouping_code} {
    set result [dict create]
    upvar 1 $varname var
    foreach var $lst {
        set key [uplevel 1 $grouping_code]
        dict lappend result $key $var
    }
    return $result
}

例如,对于从 0 到 9 的数字列表,按"模 3"分组

set groups [groupby n {0 1 2 3 4 5 6 7 8 9} {expr {$n % 3}}]
# {0 {0 3 6 9} 1 {1 4 7} 2 {2 5 8}}

或者,对于您的问题

set a {CSCvi6:sunil CSCvi7:sunil CSCvi8:parames CSCvi87:sunil CSCvi878:sunil CSCvi89:arun CSCvi95:sunil CSCvj3:sunil CSCvj1:arun}
set groups [groupby elem $a {lindex [split $elem :] end}]
# {sunil {CSCvi6:sunil CSCvi7:sunil CSCvi87:sunil CSCvi878:sunil CSCvi95:sunil CSCvj3:sunil} parames CSCvi8:parames arun {CSCvi89:arun CSCvj1:arun}}

要从分组中过滤名称,请执行以下操作:

set groups [dict map {key value} $groups {lmap pair $value {lindex [split $pair :] 0}}]
# {sunil {CSCvi6 CSCvi7 CSCvi87 CSCvi878 CSCvi95 CSCvj3} parames CSCvi8 arun {CSCvi89 CSCvj1}}

我从 Ruby 那里得到了一些灵感来实现这个实现。

最新更新