Home > Software design >  TCL code to loop through a string and print only value greater than
TCL code to loop through a string and print only value greater than

Time:12-16

A file consists of multiple input strings that consist of a fixed letter "a" followed by [0-15], space, and then a decimal value. Each of these sets is enclosed in curly braces and separated by the next set by a space. I'm looking for the set where the decimal value exceeds 5.0000 but dropping the highest value which is 113.1600 (first line) and 208.1150 (second line). For eg. Output of the first string will be {a7 32.7832} & no output for second string.

Input:

{a7 32.7832} {a8 1.6795} {a9 0.4920} {a10 0.6235} {a11 0.4190} {a14 3.2500} {a6 1.5170} {a12 0.2620} {a13 0.0410} {a3 2.6730} {a4 2.7620} {a5 0.7490} {a2 2.0300} {a15 113.1600}
{a3 1.0995} {a5 0.3180} {a6 0.3395} {a7 0.5600} {a8 1.4035} {a9 1.1810} {a10 0.4340} {a11 0.3430} {a13 0.6970} {a14 208.1150} {a2 1.4630} {a4 1.0820}
{a3 1.0995} {a5 0.3180} {a6 0.3395} {a7 0.5600} {a8 6.0835} {a9 1.1810} {a10 0.4340} {a11 0.3430} {a13 0.6970} {a14 208.1150} {a2 1.4630} {a4 1.0820}

Output:

{a7 32.7832}
{a8 6.0835}

CodePudding user response:

It's pretty easy to do in TCL as strings enclosed in brackets are treated as lists. Then you just loop over all the value, skip anything less than 5, and build a list of everything that isn't the highest values.

set values {{a7 32.7832} {a8 1.6795} {a9 0.4920} {a10 0.6235} {a11 0.4190} {a14 3.2500} {a6 1.5170} {a12 0.2620} {a13 0.0410} {a3 2.6730} {a4 2.7620} {a5 0.7490} {a2 2.0300} {a15 113.1600}}

set values2 {{a3 1.0995} {a5 0.3180} {a6 0.3395} {a7 0.5600} {a8 1.4035} {a9 1.1810} {a10 0.4340} {a11 0.3430} {a13 0.6970} {a14 208.1150} {a2 1.4630} {a4 1.0820}}

set values3 {{a3 1.0995} {a5 0.3180} {a6 0.3395} {a7 0.5600} {a8 6.0835} {a9 1.1810} {a10 0.4340} {a11 0.3430} {a13 0.6970} {a14 208.1150} {a2 1.4630} {a4 1.0820}}


proc calcValues {values} {
    set outputs [list]
    set max {}

    foreach value $values {
        set num [lindex $value 1]

        if {$num < 5.0} {
            continue
        }

        if {$max eq {}} {
            set max $value
            continue
        }

        if {[lindex $max 1] < $num} {
            lappend outputs $max
            set max $value
        } else {
            lappend outputs $value
        }
    }

    return $outputs
}

puts [calcValues $values]
puts [calcValues $values2]
puts [calcValues $values3]

CodePudding user response:

set lines {
    {{a7 32.7832} {a8 1.6795} {a9 0.4920} {a10 0.6235} {a11 0.4190} {a14 3.2500} {a6 1.5170} {a12 0.2620} {a13 0.0410} {a3 2.6730} {a4 2.7620} {a5 0.7490} {a2 2.0300} {a15 113.1600}}
    {{a3 1.0995} {a5 0.3180} {a6 0.3395} {a7 0.5600} {a8 1.4035} {a9 1.1810} {a10 0.4340} {a11 0.3430} {a13 0.6970} {a14 208.1150} {a2 1.4630} {a4 1.0820}}
    {{a3 1.0995} {a5 0.3180} {a6 0.3395} {a7 0.5600} {a8 6.0835} {a9 1.1810} {a10 0.4340} {a11 0.3430} {a13 0.6970} {a14 208.1150} {a2 1.4630} {a4 1.0820}}
}

set maxima [lmap line $lines {
    set sorted [lsort -real -index 1 $line]
    set second_max [lindex $sorted end-1]
    if {[lindex $second_max end] <= 5.0} then continue else {set second_max}
}]

result

{a7 32.7832} {a8 6.0835}
  • Related