获取列表的特定索引列表中的项目

Get items in specific index list of lists

我有一个键值列表,例如:

set x {{a 1} {b 2} {c 3}}

我需要提取所有子列表中index=1的所有项目得到:

{1 2 3}

你可以使用这个:

$ set y {}
$ foreach sublist $x { lappend y  [lindex $sublist 1]}
$ puts $y
1 2 3

TCL 8.6 或更高版本的解决方案:

使用 lmap 遍历 x 而不在任何地方保存值,在一行中:

$ lmap sublist $x {lindex $sublist 1}

参考资料: lmap,tcl.tk

我使用了以下功能:

proc MapList {Var List Script} {
    if {![llength $List]} {return $List}
    upvar 1 $Var Item
    foreach Item $List {lappend Res [uplevel 1 $Script]}
    return $Res
}

并像这样使用它:

MapList Arg $x {lindex $Arg 1}

一个解决方案是征召 dict values 命令:

dict values [concat {*}{{a 1} {b 2} {c 3}}]

工作原理:dict values 收集一个列表,该列表由另一个列表中的所有其他项目(从第二个开始)组成。这旨在用于字典,但由于字典基本上只是偶数大小的列表,因此它适用于任何偶数大小的列表,但有一个警告:如果任何键出现多次, dict values 的结果将仅包含与该键关联的最后一个值。

通过将子列表作为参数单独传递给 concat.

,可以轻松地将包含两项子列表的列表转换为偶数大小的列表

另一种方法是使用其他答案中提到的方法之一遍历列表,或者像这样:

set res {}
for {set i 0} {$i < [llength $x]} {incr i} {
    lappend res [lindex $x $i 1]
}
set res

这类似于

set res {}
foreach item $x {
    lappend res [lindex $item 1]
}
set res

(或对应的lmap item $x {lindex $item 1})

但确实提供了以下选项:1) 从索引 ≠ 0 开始,2) 在列表末尾之前结束,以及 3) 按两个(或更多)项目步骤遍历列表。

文档:concat, dict, for, foreach, incr, lappend, lindex, llength, lmap, set