2016-05-10 6 views
0

Ich habe eine große Liste, die ich in einer Datei ohne Zeilenumbruch setzen:TCL convert Liste String mit neuen Zeilen jeden X Listenelement

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

aber ich brauche eine Linie alle 8 Elemente einzufügen brechen, da die resultierende Datei nicht korrekt interpretiert wird.

Ich frage mich, ob es eine Art eingebaute Funktion gibt, das zu tun?

Wenn nicht, habe ich über eine Prozedur nachgedacht, die einen String mit Zeilenumbrüchen oder eine Funktion zurückgibt, die alle 8 Elemente in die Datei schreibt.

hatte jemand das gleiche Problem?

Gibt es so etwas wie dies in TCL: How do you split a list into evenly sized chunks?

Dank.

+0

sollte jede Zeile mit einem Komma enden oder nicht? –

+0

nein es ist nicht notwendig, – user1616685

Antwort

2

Sie können den Befehl lrange verwenden, um den erforderlichen Bereich von Listenelementen zu erhalten und bis zum Ende durchlaufen zu lassen.

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] 
} 

Ausgang:

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

Auch wenn die endIdx die tatsächliche Größe der Liste überschreitet, ist es kein Problem. Dies ist der Grund, wenn die Schleife zum zweiten Mal ausgeführt wird, wird endIdx 15 sein und wird Listenelemente nur bis zum 11. Indexelement zurückgeben.

+0

danke das, wie auch immer die elemente durch kommas getrennt werden müssen, ist das mit lrange möglich? – user1616685

+0

puts ", [format"% s "[join [lrang $ liste $ startIdx $ endIdx]", "]]" funktioniert, danke! – user1616685

+1

Simple '[Join [lrange $ liste $ startIdx $ endIdx]", "]' funktioniert auch ... ohne Format. –

2

Eine Möglichkeit besteht darin, einen Befehl zu definieren, der bei Ausführung als Coroutine Teile ("Chunks") einer Liste einzeln zurückgibt. Dieser Befehl benötigt eine Liste, eine Länge und einen optionalen Startindex (Standard 0). Wenn die Liste erschöpft ist, wird für immer eine leere Liste zurückgegeben.

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

Erstellen Sie den Koroutine Befehl, um die Liste bereitstellt und die Länge:

coroutine nextchunk chunk $input 8 

es wie folgt verwendet:

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

Dokumentation: coroutine, expr, for, incr, join, llength, lrange, proc , puts, set, while, yield

+1

Schöne Lösung, aber ich sah diese Fehlermeldung: "aufgerufen" Pause "außerhalb einer Schleife" –

+1

@Glennjackman: es funktionierte für mich in 'tkcon', weil es mit den Ausnahmen mischt. In anderen Shells wird diese Fehlermeldung angezeigt. Eine Erinnerung, Code immer in verschiedenen Shells zu testen ...Ich habe eine alternative Lösung gepostet, die in allen drei Shells funktioniert. –