nowlin@ihuxy.UUCP (01/04/88)
> I need to sort a list of records according to complicated sort criteria, > The standard icon sort() routine is not making this task easy. What I need > is something more like the C library qsort routine that lets me provide my > own comparison routine. > > Is there any hope of my finding something like this in icon, or am I > missing some elegant way to do this with the existing sort() routine? > > --dave yost I'm not sure this is what you had in mind but the procedure enclosed is handy for sorting records and can be modified to work with your own comparison routines fairly easily. I don't know of any way to use the builtin sort() for anything other than standard types. This recsort() procedure only sorts on one field of a record but it wouldn't be too hard to pass it a list of the fields in the record that should be sorted on instead of a single value. The way the intermediate table of records is maintained will make it fairly easy to sort on multiple keys. Hope this is helpful. (Sorry for the lack of comments.) Jerry Nowlin (...!ihnp4!ihuxy!nowlin) # This example program sorts a UNIX style password file. The first # argument to the program should be the field in each password entry to # sort on. The program has a limit of the first 20 entries built in but # it can be removed to test the program on the whole password file. The # program uses the recsort() procedure to sort a list of records. record passwd(name,pass,uid,gid,info,logdir,shell) procedure main(args) if *args = 0 then stop("I need a numeric field index to sort on") users := [] in := open("/etc/passwd","r") every line := !in\20 do line ? { user := passwd() user.name := tab(upto(':')) & move(1) user.pass := tab(upto(':')) & move(1) user.uid := tab(upto(':')) & move(1) user.gid := tab(upto(':')) & move(1) user.info := tab(upto(':')) & move(1) user.logdir := tab(upto(':')) & move(1) user.shell := tab(0) put(users,user) } close(in) write("UNSORTED: ",image(users)," ",image(users[1])) every user := !users do write( user.name," : ", user.pass," : ", user.uid," : ", user.gid," : ", user.info," : ", user.logdir," : ", user.shell) stuff := recsort(users,!args) write("\nSORTED: ",image(stuff)," ",image(stuff[1])) every user := !stuff do write( user.name," : ", user.pass," : ", user.uid," : ", user.gid," : ", user.info," : ", user.logdir," : ", user.shell) end procedure recsort(recs,index) tempt := table() every rec := !recs do (/tempt[rec[index]] := [ rec ]) | put(tempt[rec[index]],rec) templ := sort(tempt,1) newrecs := [] every pair := !templ do every put(newrecs,!pair[2]) return newrecs end