我有一个很大的列表,我把它放在一个文件中没有任何换行符:
puts $output_file ", [format " %s" [join $elems ","]]"
但是我需要每8个元素插入一个换行符,因为生成的文件没有被正确解释。
我想知道是否有某种内置功能可以做到这一点?
如果不是,我正在考虑一个过程返回一个带换行符的字符串或一个函数写入每8个元素的文件。
有人有同样的问题吗?
TCL中有类似的内容:How do you split a list into evenly sized chunks?
感谢。
答案 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 ", "]
}
文档:coroutine,expr,for,incr,join,llength,lrange,{{3 }},proc,puts,set,while