0

suppose I have a list like below:

set listNums {0 -1 5 5 -5 1 10 100 -10 -10 1000}

I want to sort it using the absolute values. I picked up the below from another script. I am having a tough time understanding this. Can someone help me understand what is going on in the below script? I used "puts" to print out values at each stage but I still did not get it!

How does "a" and "b" get updated? Why do we need "return 0" ?
Sorry if I am asking rudimentary questions.

lsort -command {apply {
  {a b}
  {
    if {[expr {abs($a)] < [expr {abs($b)}]} {return -1}
    if {[expr {abs($a)] > [expr {abs($b)}]} {return 1}
    if {$a < $b} {return -1}
    if {$a > $b} {return 1}
    return 0
  }
}} $listNums
user3512999
  • 139
  • 1
  • 8

1 Answers1

2

Every time two elements are compared during the sorting, one is passed into this invocation as a, and the other as b.

The result of the comparison can be "lesser than", "greater than", or "equal", encoded as the return values -1, 1, or 0.

Also, try

if {abs($a) < abs($b)} ... 

instead: the condition to if implicitly invokes expr.

And don't compare twice.

Documentation: apply, if, lsort

Peter Lewerin
  • 13,140
  • 1
  • 24
  • 27
  • Thank you Peter. I am still not clear how the sorted list gets printed in the end. If I take the first two elements in my list, then a = 0 and b=-1. since abs(0) < abs(-1), the return value will be -1. Up on next execution, a = 5 and b = 5. So, the return value will be 0. Is this the correct understanding? I am not clear, how lsort prints the sorted list, based on this. I am missing something to complete my understanding. – user3512999 Jan 04 '18 at 10:45
  • lsort doesn't print the list. It creates and returns a new list containing the same elements ordered according to the command it was given. The return values of the invocation of the command are only seen by lsort as it compares the elements to each other. To put it simply, when the sorting is in increasing order a return value of 0 or 1 means that the current pair of elements are in order, while a result of -1 tells lsort that the elements are in wrong order. – Peter Lewerin Jan 04 '18 at 10:58
  • When using tclsh in interactive mode, the tcl shell will print the result from the last command executed. But if you put the command in a file and: `tclsh myfile.tcl`, there will be no output unless you put in a `puts`. – Brad Lanam Jan 04 '18 at 11:03
  • Peter, I used a "puts [list $a $b]" right before the first "if" statement, to see how $a and $b change. It looks like lsort is using mergesorting. Do you happen to know if this is true? If it is, then I think I understand the whole process now. Thank you so much for the help. Thank you Brad as well for the additional insights. – user3512999 Jan 04 '18 at 11:25
  • 1
    @user3512999: according to the documentation it is indeed mergesort. – Peter Lewerin Jan 04 '18 at 12:32