我有一个包含列表的列表。
{
{1, A},
{2, A},
{4, A},
{6, B},
{2, B},
{7, C}
}
如何重复搜索第二个元素并添加索引?
预期产出:
{
{1, A<0>},
{2, A<1>},
{4, A<2>},
{6, B<0>},
{2, B<1>},
{7, C}
}
答案 0 :(得分:1)
Tcl列表通常没有除元素之外的空格之外的分隔符,并且如果有一个子列表由大括号内的项表示,则在子列表后明确禁止使用逗号。
set list {
{1 A}
{2 A}
{4 A}
{6 B}
{2 B}
{7 C}
}
set res {}
foreach item $list {
set letter [lindex $item 1]
if {[info exists num($letter)]} {
incr num($letter)
} else {
set num($letter) 0
}
lset item 1 $letter<$num($letter)>
lappend res $item
}
该算法包括遍历列表列表foreach
并查看子列表中第二个元素(索引#1)的字母。数组num
用于计算每个字母发生的次数。如果num($letter)
存在,我们之前已经计算了这封信,并且只是增加了计数。如果没有,则为新字母,我们将计数设置为0.我们将该字母与包含该计数的后缀一起写回(使用lset
),最后将更改的子列表添加到列表{{ 1}}。
如果你有res
,你可以稍微简化一下代码:
lmap
文档: foreach, if, incr, info, lappend, lindex, lmap (for Tcl 8.5), lmap, lset, set
答案 1 :(得分:1)
使用Tcl 8.6
proc update {list} {
lmap elem $list {
set val [lindex $elem end]
set n [expr {[incr count($val)] - 1}]
lset elem end "$val<$n>"
}
}
set a {{1 A} {2 A} {4 A} {6 B} {2 B} {7 C}}
set new [update $a]