Abdelrahman Magdy
Abdelrahman Magdy

Reputation: 3

Inserting single curly braces to Tcl list elements

I have a report file having multiple lines in this form:

str1 num1 num2 ... numN str2

Given that (N) is not the same across lines. These numbers represent coordinates, so I need to enclose each point with curly braces to be:

{num1 num2} {num3 num4} and so on...

I have tried this piece of code:

set file_r [open file.rpt r]
set lines [split [read $file_r] "\n"]
close $file_r
foreach line $lines {
    set items [split $line]
    set str1 [lindex $items 0]
    set str2 [lindex $items [expr [llength $items] - 1]]
    set box  [lrange $items 1 [expr [llength $items] - 2]]
    foreach coord $box {
        set index [lsearch $box $coord]
        set index_rem [expr $index % 2]
        if {index_rem == 0} {
            set box [lreplace $box $index $index "{$coord"]
        } else {
            set box [lreplace $box $index $index "$coord}"]
        }
    }
    puts "box: $box"
}

This gives me a syntax error that a close-brace is missing. And if I try "\{$coord" the back-slash character gets typed in the $box.

Any ideas to overcome this?

Upvotes: 0

Views: 83

Answers (1)

Chris Heithoff
Chris Heithoff

Reputation: 1863

There are a few things you could improve to have better and simpler Tcl style.

  1. You usually don't need to use split to form a list from a line if the line is already space separated. Space separated strings can almost always be used directly in list commands. The exceptions are when the string contains { or " characters.
  2. lindex and lrange can take end and end-N arguments.

This plus Donal's comment to use lmap will result in this:

set file_r [open file.rpt r]
set lines [split [read $file_r] "\n"]
close $file_r
foreach line $lines {
    set str1     [lindex $line 0]
    set str2     [lindex $line end]
    set numbers  [lrange $line 1 end-1]
    set boxes [lmap {a b} $numbers {list $a $b}]
    foreach box $boxes {
        puts "box: {$box}"
    }
}

Upvotes: 1

Related Questions