The first problem is that you print a line of an output for each single line of an input. While, as I understood your problem description, your output will not match the input line-by-line. So, at least the last puts
is misplaced; it could be useful for the debug, but not for the output of the final result.
Second, you re-set key_start_end_data
every cycle iteration to an empty dict. Probably you wanted to do that only before the cycle or when it switches to a new keyword? Also, before resetting it you have to copy its resulting value to some non-volatile variable, but you didn't used keyword_numbers
for anything. Was it intended for collecting the resulting data?
Third, this is wrong use of dict lappend
. It is intended to append to a list which is the value of some dict item; you don't have such a structure nowhere and it is not useful for this problem. Probably you wanted to use dict set
which replaces the dictionary value for the given key, or creates the key and sets its to the value, if it wasn't exist:
dict set key_start_end_data bit_start $number
Finally, while your code could be debugged, it is too verbose and has too many variables, so it's hard to read and to understand. Compare it with the following:
set keyword_numbers {}
foreach item $data {
if {[regexp {(\w+)\[(\d+)\]} $item -> keyword number]} {
if [dict exists $keyword_numbers $keyword] {
dict set keyword_numbers $keyword bit_start \
[expr {min([dict get $keyword_numbers $keyword bit_start], $number)}]
dict set keyword_numbers $keyword bit_end \
[expr {max([dict get $keyword_numbers $keyword bit_end], $number)}]
} else {
dict set keyword_numbers $keyword \
[dict create bit_start $number bit_end $number]
}
}
}
puts $keyword_numbers
if {[regexp ...]}
makes it to only process lines that matched the regexp. Just a safeguard. Then, if this keyword already happened before, it replaces its bit_start and bit_end with whatever it should be considering the current line; if the keyword is new, it creates it anew with both subelements set to the number in the current line. This code will successfully process much more relaxed input, for instance, you can shuffle the lines of an input and the result will still be the same. I wrapped long lines; this is not necessary, but just looks better here.
I didn't processed the output to output lines. To do that, instead of last single puts
, you can do the following:
dict for {key val} $keyword_numbers {
puts "$key {$val}"
}
It puts values in TCL's dict format, without colons