Add an opening brace to the beginning of a list in tcl

400 views Asked by At

I am trying to find the Cartesian product of two sets in tcl. My logic is ready, but I need to beautify the output and put an opening brace at the beginning of the list. I am able to append at the end by using append command, but it is throwing up error while doing so for the beginning of the list. Following is the code :

set a {0 1}
set b {1 2 3}
set s {}
append s "\{"                                              ### this is where the problem is
for {set i 0} { $i < 2 } {incr i} {
         for {set j $i} { $j < 2 } {incr j} {
                  set x "([lindex $a $i],[lindex $b $j])"
                  lappend s "$x,"
                  
         }
         if {$j == 2} {
                  set x "([lindex $a $i],[lindex $b $j])"
                  lappend s "$x"
               }
      }
      append s }
      puts $s

Now using

append s "\{" 

gives

unmatched open brace in list

On the other hand, using

append s "\\{"

gives the following output :

\{ (0,1), (0,2), (0,3) (1,2), (1,3)}

Is there a way I can remove the first slash and the space between the opening brace and the first parenthesis?

2

There are 2 answers

8
Donal Fellows On

You're probably better off building the output as a list that you then convert to a string:

set a {0 1}
set b {1 2 3}

# The list of cells to appear in the output
set cells {}
# [foreach] is nicer than [for]/[lindex]
foreach i $a {
    foreach j $b {
        # Format a single cell
        lappend cells "($i,$j)"
    }
}
# Produce the result string with [string cat] and [join]
set result [string cat "{" [join $cells ", "] "}"]
puts $result
0
Schelte Bron On

The advantage of using a list is that you can easily join it with commas in between, so you don't have to resort to treating the last element special, like you are doing. Putting the whole thing in braces is most easily done at the end, after joining the list:

set a {0 1}
set b {1 2 3}
set s {}
for {set i 0} {$i < 2} {incr i} {
    for {set j $i} {$j < 3} {incr j} {
        set x "([lindex $a $i],[lindex $b $j])"
        lappend s $x
    }
}
puts "{[join $s ", "]}"