Home > Net >  I need to insert the output of the count, incremented from a loop 'for' within a varyable
I need to insert the output of the count, incremented from a loop 'for' within a varyable

Time:11-30

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"

Result enter image description here


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 the list 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 with list 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

  • Related