TCL将列表转换为每个X列表元素的新行字符串

时间:2016-05-10 11:29:40

标签: string list tcl

我有一个很大的列表,我把它放在一个文件中没有任何换行符:

puts $output_file ", [format " %s" [join $elems ","]]"

但是我需要每8个元素插入一个换行符,因为生成的文件没有被正确解释。

我想知道是否有某种内置功能可以做到这一点?

如果不是,我正在考虑一个过程返回一个带换行符的字符串或一个函数写入每8个元素的文件。

有人有同样的问题吗?

TCL中有类似的内容:How do you split a list into evenly sized chunks?

感谢。

2 个答案:

答案 0 :(得分:2)

您可以使用lrange命令获取所需的列表元素范围并将其循环直至结束。

set input {1 2 3 4 5 6 7 8 9 10 11 12} 
for {set startIdx 0} {$startIdx<[llength $input]} {incr startIdx 8} {
    set endIdx [expr {$startIdx+7}]
    puts [lrange $input $startIdx $endIdx]
}

输出

1 2 3 4 5 6 7 8
9 10 11 12

即使endIdx超过列表的实际大小,也不是问题。这就是原因,当循环第二次运行时,endIdx将为15,Tcl将仅返回列表元素,直到第11个索引元素。

答案 1 :(得分:2)

一种方法是定义一个命令,当作为协程运行时,将返回列表的部分(“块”),一次一个。此命令采用列表,长度和可选的起始索引(默认为0)。当它已经耗尽了列表时,它将永远返回一个空列表。

proc chunk {list n {i 0}} {
    yield
    set m [expr {$n - 1}]
    while 1 {
        yield [lrange $list $i $i+$m]
        incr i $n
    }
}

创建coroutine命令,提供列表和长度:

coroutine nextchunk chunk $input 8

像这样使用:

for {set chunk [nextchunk]} {[llength $chunk] > 0} {set chunk [nextchunk]} {
    puts [join $chunk ", "]
}

文档:coroutineexprforincrjoinllengthlrange,{{3 }},procputssetwhile