Having a tablelist I want to delete all rows containing a string in the first column.
set Joints [.dsm.nb.f11.jointData_f11 getcolumns cJoint ]
set killrow 0
foreach Joint $Joints {
if { $Joint eq "" } {
.dsm.nb.f11.jointData_f11 delete $killrow $killrow
}
incr killrow
}
The problem is that the row indexes of the table changes while rows get deleted, so that after the first delete command everything gets messd upp. What is the best way to deal with this Problem? Is there a build in feature i could use?
The simplest way of making this work is to go through the list backwards. lreverse helps a lot.
set Joints [.dsm.nb.f11.jointData_f11 getcolumns cJoint]
set killrow 0
set rowsToKill {}
foreach Joint $Joints {
if {$Joint eq ""} {
lappend rowsToKill $killrow
}
incr killrow
}
foreach killrow [lreverse $rowsToKill] {
.dsm.nb.f11.jointData_f11 delete $killrow $killrow
}
Yes, you're iterating over the list a few times. It's still simpler to do it this way than to try to do it any other.
Related
I got three different entries "10576.53012.46344.35174" , "10" and "Doc-15" in foreach loop. Out of these 3 entries, i want 10576.53012.46344.35174. How can i verify that current string contains multiple . and numbers.
Im new to TCL, Need suggestion
This is the sort of task that is a pretty good fit for regular expressions.
The string 10576.53012.46344.35174 is matched by a RE like this: ^\d{5}(?:\.\d{5}){3}$ though you might want something a little less strict (e.g., with more flexibility in the number of digits per group — 5 — or the number of groups following a . — 3).
You test if a string matches a regular expression with the regexp command:
if {[regexp {^\d{5}(?:\.\d{5}){3}$} $theVarWithTheString]} {
puts "the regular expression matched $theVarWithTheString"
}
An alternative approach is to split the string by . and check that each group is what you want:
set goodBits 0
set badString 0
foreach group [split $theVarWithTheString "."] {
if {![string is integer -strict $group]} {
set badString 1
break
}
incr goodBits
}
if {!$badString && $goodBits == 4} {
puts "the string was OK"
}
I greatly prefer the regular expression approach myself (with occasional help from string is as appropriate). Writing non-RE validators can be challenging and tends to require a lot of code.
I want a code/some hints of comparison of one array with another array.
If one element of array matches with an element in the other array, return 0 with puts statement, otherwise one with some puts statement.
I try to search on the Internet but can't find any useful stuff.
array set foodColor {
Apple red
Banana yellow
Lemon yellow
Carrot orange
}
array set citrusColor {
Lemon yellow
Orange orange
Lime green
}
# build up a list of non-citrus foods
foreach k [array names citrusColor] {
if {![info exists foodColor($k)]} {
puts $k;
}
}
In this code, output shows those value that does not match with values in other array.
But I don't want character or string comparison in array ,I want full array comparison with the other array if match show output match else not match.
The syntax of array set is as follows,
array set arrayName list
Sets the values of one or more elements in arrayName. list must have a
form like that returned by array get, consisting of an even number of
elements. Each odd-numbered element in list is treated as an element
name within arrayName, and the following element in list is used as a
new value for that array element. If the variable arrayName does not
already exist and list is empty, arrayName is created with an empty
array value.
You should get the following error
wrong # args: should be "array set arrayName list"
The code can be rewritten as,
array set food {
Apple red
Banana yellow
Lemon yellow
Carrot orange
}
array set citrus {
Lemon yellow
Orange orange
Lime green
}
foreach k [array names citrus] {
if {[info exists food($k)]} {
puts "The key '$k' is available in both arrays"
}
}
Output :
The key 'Lemon' is available in both arrays
Do you want this?
if { [info exists citrusColor($key)] &&
[info exists foodColor($key)] &&
$citrusColor($key) eq $foodColor($key)
} {
puts "Key $key is in both arrays with the same value"
return 0
} else {
puts "Key $key is either missing or has a different value"
return 1
}
I have a JSON string strcutred like so:
[{"ip":"", "comment":""}, {"ip":"", "comment":""}]
I'm trying to figure out how to remove one of these objects by identification from the IP and/or comment keys.
The closest i've got so far is this:
my $jsn = decode_json('[{"ip":"1.2.3.4", "comment":"one"}, {"ip":"10.10.10.10","comment":"two"}]');
foreach(#{$jsn}){
if($_->{ip} eq '1.2.3.4'){
print "Found!";
splice #{$jsn}, $_, 1;
}
}
I know splice doesn't work in this example. If i could get the index of the object (ideally without a counter), i think i could then remove the correct object.
grep is your friend here. It creates a new list of elements in an existing list that match an expression.
my #filtered = grep { $_->{ip} ne '1.2.3.4' } #$jsn;
I have an array containing the results of a mysql query on "Category", "Group" and "Subgroup" for stock items. I need to build a dynamic menu but the content of the current line of the array I am building depends on a column in the next line.
I have looked up and found many examples but all of them check the whole line of the array (the mysql row) I only want to check one item in the line of the array (one mysql column). I need something like
for ( $ix = 0; $ix < (length(current_result) - 1); $ix++) {
if (current_result[$ix, Catagory] = current_result[$ix + 1, Catagory]) {
echo some code
} else {
echo some other code
}
}
some code to handle the last line of the array
Assuming you have an associative array of rows, you're simply missing proper array syntax:
for( .... ){
$thiscat = $current_result[$ix]['Category'];
$nextcat = $current_result[$ix+1]['Category'];
}
I have code here
proc checkPrime {no} {
set i 1
set count 0
while {$i < $no} {
if {{$no%$i} eq 0} {
incr count
}
if {$count eq 2} {
puts "the number is prime number"
return
}
incr i
}
}
I want to put the whole procedure into a single comment, I don't want to have to put # before each line.
Is there any possibility to comment multiple lines in Tcl, as there is in Java using /* .. */?
I also want some of the text will be put into a single comment
Apart from the if {0} .. which is idiomatic (and one that most tcl programmers recognize) you can also use any other construct and stuff the things you want commented out in brace quotes. The real mechanism preventing execution here is that things inside brace quotes don't get substituted.
Here are some of my favourites. I like them because they are self-documenting:
set COMMENTED_OUT {
commented out stuff
}
and
proc COMMENTED_OUT {} {
commented out stuff...
}
I tend to prefer the proc because the block of commented out text is really a block of code.
Note that tcl does not compile proc bodies until first execution so commenting out using a proc is as cheap as set and if {0} ...
Use something along these lines:
if { 0 } {
a section
of
"commented" code
}