Tcl 8.5多列表重映射算法咨询:转换为指定嵌套列表
Tcl 8.5 实现多列表键值对按位置配对
针对你需要将多个{键 {元素1 元素2 ...}}格式的列表,转换为按位置分组的键值对嵌套列表的需求,这里提供两种适配Tcl 8.5的实现方案:
方案1:以最短列表长度为准(仅处理所有列表都有元素的位置)
这个方案会遍历到所有元素列表中最短的那个的长度,超出短列表长度的位置会被忽略:
proc zip-key-lists {args} { # 拆分输入的每个列表,提取键和对应的元素列表 set keys [list] set val-lists [list] foreach item $args { lassign $item key vals lappend keys $key lappend val-lists $vals } # 计算所有元素列表的最小长度,确定迭代次数 set min-length [llength [lindex $val-lists 0]] foreach lst $val-lists { set current-len [llength $lst] if {$current-len < $min-length} { set min-length $current-len } } set max-idx [expr {$min-length - 1}] # 按索引遍历,生成分组的键值对 set result [list] for {set i 0} {$i <= $max-idx} {incr i} { set group [list] foreach key $keys lst $val-lists { lappend group [list $key [lindex $lst $i]] } lappend result $group } return $result }
使用示例
# 测试等长列表 set input1 [list {a {1 2 3}} {b {4 5 6}}] puts [zip-key-lists {*}$input1] # 输出:{{{a 1} {b 4}} {{a 2} {b 5}} {{a 3} {b 6}}} # 测试不等长列表 set input2 [list {x {10 20 30}} {y {40 50}} {z {60 70 80 90}}] puts [zip-key-lists {*}$input2] # 输出:{{{x 10} {y 40} {z 60}} {{x 20} {y 50} {z 70}}}
方案2:以最长列表长度为准(短列表补空值)
如果需要处理到最长列表的最后一个元素,短列表没有对应元素的位置会补空字符串:
proc zip-key-lists-longest {args} { # 拆分输入的每个列表,提取键和对应的元素列表 set keys [list] set val-lists [list] foreach item $args { lassign $item key vals lappend keys $key lappend val-lists $vals } # 计算所有元素列表的最大长度,确定迭代次数 set max-length 0 foreach lst $val-lists { set current-len [llength $lst] if {$current-len > $max-length} { set max-length $current-len } } set max-idx [expr {$max-length - 1}] # 按索引遍历,生成分组的键值对,短列表补空 set result [list] for {set i 0} {$i <= $max-idx} {incr i} { set group [list] foreach key $keys lst $val-lists { set val [expr {$i < [llength $lst] ? [lindex $lst $i] : ""}] lappend group [list $key $val] } lappend result $group } return $result }
使用示例
set input [list {x {10 20 30}} {y {40 50}} {z {60 70 80 90}}] puts [zip-key-lists-longest {*}$input] # 输出:{{{x 10} {y 40} {z 60}} {{x 20} {y 50} {z 70}} {{x 30} {y ""} {z 80}} {{x ""} {y ""} {z 90}}}
算法思路说明
- 拆分输入:遍历所有输入列表,将每个列表的键和元素列表分别存入两个集合,方便后续批量处理。
- 确定迭代范围:根据需求选择以最短或最长元素列表的长度作为循环的终止条件。
- 生成分组:逐个索引遍历,对每个键取出对应元素列表中该位置的值(短列表补空),组成键值对后再整合为一组,最终收集所有组得到结果。
内容的提问来源于stack exchange,提问作者Turro75
相关产品推荐
相关产品推荐

