Training, Open Source computer languages
PerlPHPPythonMySQLApache / TomcatTclRubyJavaC and C++LinuxCSS 
Search for:
Home Accessibility Courses Diary The Mouth Forum Resources Site Map About Us Contact
 
For 2023 (and 2024 ...) - we are now fully retired from IT training.
We have made many, many friends over 25 years of teaching about Python, Tcl, Perl, PHP, Lua, Java, C and C++ - and MySQL, Linux and Solaris/SunOS too. Our training notes are now very much out of date, but due to upward compatability most of our examples remain operational and even relevant ad you are welcome to make us if them "as seen" and at your own risk.

Lisa and I (Graham) now live in what was our training centre in Melksham - happy to meet with former delegates here - but do check ahead before coming round. We are far from inactive - rather, enjoying the times that we are retired but still healthy enough in mind and body to be active!

I am also active in many other area and still look after a lot of web sites - you can find an index ((here))
Sorting

Posted by susyq78 (susyq78), 31 August 2003
Hi - I'm hoping someone can help me...

I'm using a Mclistbox and want to sort on a particular column.  I have code to sort and it works except that in the column if there are blank entries it puts them first.  I would like to be able to put them last but can't figure out how to do it.  Here is the code that I have at the moment:

set data [$w get 0 end]
   set index [lsearch -exact [$w column names] $id]
   set result [lsort -dictionary -index $index $data]

   $w delete 0 end

   # ... and add our sorted data in
   eval $w insert end $result

Can anyone help??

Thanks

Susan

Posted by admin (Graham Ellis), 1 September 2003
Code:
proc blankslast {first second} {
       if {$first == ""} {return 1}
       if {$second == ""} {return -1}
       return [string compare $first $second]
       }

set index {"" "John" "" "Mary" "Joan" "Dick" "Terry"}
set result [lsort -command blankslast $index]
puts $result


Results:

Code:
[graham@pasanda fred]$ tcl sorter.tcl
Dick Joan John Mary Terry {} {}
[graham@pasanda fred]$


If you want to sort in a different way to the ways provided, you need to provide a proc to tell Tcl how to know which of two records is logically first - the proc must return -ve, 0, +ve for "they're right as they are", "they are the same" and "they need swapping".  When you run lsort with the -command option, you pass it the name of the proc and it will call it internally as many times as it needs to. Neat!


Posted by susyq78 (susyq78), 1 September 2003
Thanks for your help - it works except that I had it sorting using the -dictionary command because I had numbers between 1 and 10 to sort and now it doesn't sort them correctly.  Silly question, but is there any way you can specify the string compare to work on integers?  

Another question that you may be able to help with - I also have a column of dates that I want to format and sort, if the user enters a string in the form DD/MM/YYYY how can I format it as a date and sort on it.

Thanks for all of your help

Susan

Posted by admin (Graham Ellis), 2 September 2003
Two alternatives - either

a) add an extra section to the comparator - if one value is numeric and the other is not, return either a 1 or -1, if both are numeric use a < or > test, and if neither is numeric stick with the string comparison.

b) Revert to your original code, and afetr sorting use lsearch to find the first non-blank element.  You can then use two lranges to divide your list, and then you can rejoin them the other way around.

With the dates, I would use a regular expression match to extract the day, month and year (a very flexible approach which will allow for multiple formats later as you can't guarantee that you user will nicely stick with  dd/mm/yyyy), and rejoin the results into a variable of the format yyyymmdd, which is naturally sortable.  You also ask about formatting the date - that's going to differ depending on the country and requirement you're formatting for - it could be
    2nd September 2003
    September 2, 2003
    2 sep 2003
and many other formats.  With the elements from your regular expression extraction above, you should be able to produce any of these in a few lines of code.   By the way - you'll probably want to refer to the date in its "human" form, and other data associated with it, after you've sorted.  Trick - hold the data associated with each record in an array, with the array element name being the date formatted for sorting.



This page is a thread posted to the opentalk forum at www.opentalk.org.uk and archived here for reference. To jump to the archive index please follow this link.

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2024: Well House Manor • 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01144 1225 708225 • FAX: 01144 1225 793803 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho