I want to list the increments in "$ i" of the loop for variable in '[list ]' mode. For then, I could calculate the values with '[expr ]'.
I will leave here a didactic example, to simplify the idea. To look:
set i 1
while {$i <= 9} {
global value
set lst [puts -nonewline "$i "]
set value [list $lst]
incr i
}
global value
# puts [expr [lindex $value 0] [lindex $value 1]]
puts "\n$value"
My difficulty is in keeping these successive increments within a variable.
In this mode:
set value $i
Only the last increment / number is added in the variable.
As I said earlier, I need to store these numbers numbers to later calculate. Something like:
puts [expr [lindex $value 0] [lindex $value 1]]
Warning - "For didactic purposes here, I made an example with ordinal number and sequence of '1 - 9'. But for my purpose that I am working at the moment .. I am receiving random numbers from one or more decimal places, I leave it very clear to the colleagues who can help do not suggest writing the list by hand. Once I am extracting lines from a file that contains 1000 lines from which it is numbered, that means that, I am working with dynamic and non-sequential number as it is in the question. I only made '1-9' to be able to exemplify the issue. After receiving the answer myself I will adapt the solution to my script.tcl."
CodePudding user response:
I made this a little more interesting by adding a random value to i
instead of incrementing by one.
set prev 0
set i 1
set i_values {}
set increments {}
while {$i <= 9} {
lappend i_values $i
lappend increments [expr {$i - $prev}]
set prev $i
set i [expr {$i rand()}]
}
puts $i_values
puts $increments
1 1.5047644425671383 2.08075066845899 2.681249232814298 3.2606203524678112 3.751028369064922 4.0385633167059 4.638428318611546 5.569515346814653 6.3491983564334 6.481541018691633 6.764665592817901 7.239382933005405 7.8137194643792345 8.687802264321506
1 0.5047644425671383 0.5759862258918518 0.6004985643553078 0.5793711196535134 0.49040801659711075 0.28753494764097765 0.5998650019056466 0.9310870282031072 0.7796830096187461 0.13234266225823355 0.28312457412626824 0.474717340187504 0.5743365313738291 0.874082799942272
CodePudding user response:
You've got two options really for incrementally building a list. The first is to use lappend
, and the second (with 8.6 onwards) is to use lset
with the index end 1
. Or you can build a list of the right length up front with lrepeat
and then lset
the values into it.
Tcl's indices are always either zero-based or end
based.
Here's an example where each element of the generated list is 1 greater than the sum of the previous two values. You need to initialise the list with two seed values.
set myList {0 1}
for {set i 0} {$i < 10} {incr i} {
set v1 [lindex $myList $i]
set v2 [lindex $myList [expr {$i 1}]]
lappend myList [expr {$v1 $v2 1}]
}
puts $myList
# 0 1 2 4 7 12 20 33 54 88 143 232
Note that you can't use foreach
to do this; that always iterates over the eemphasized textlements of a fixed (at the time of calling) list value.
CodePudding user response:
Glenn Jackman answer shows the usage of lappend
to append an element to a list
.
Chris Heithoff clarified to me in his comment that, it is a common mistake with lappend
to use the $ dollar sign in front of the variable list name.
Donal Fellows warned me before I could even fall into the temptation to do this with foreach
-, Note that you can't use foreach
to do this; that always iterates over the eemphasized textlements of a fixed (at the time of calling) list value.
#!/bin/ash
# \
exec tclsh "$0" "$@"
# list
set value {}
set i 1
while {$i <= 9} {
# Add the stdout in "$i" for list
lappend value $i
incr i
}
# Note that in this calculation, the left side is placed the even numbers and the Right are the Odd ones.
puts [expr [lindex $value 0] [lindex $value 1]]
puts [expr [lindex $value 2] [lindex $value 3]]
puts [expr [lindex $value 4] [lindex $value 5]]
puts [expr [lindex $value 6] [lindex $value 7]]
puts [expr [lindex $value 8] [lindex $value 9]]
Conclusion
I became so attached to the stdout exit of the
puts
believing that only he could build the list through thelist
that I didn't realize I could do it any other way without these two commands.Although I tried to make use of
lappend
I insisted on using in conjunction withlist
and on top of that some erroneous attempts how to use $ followed variable, like:lapped $value $lst
Now I know where I was wrong, how I could have avoided so much time spent on a simple solution that it was shown in the answers. Anyway, the use of `lapp