reverse sort

Started by pguild, March 18, 2023, 11:52:45 AM

Previous topic - Next topic

pguild

It would be helpful if there were an argument in Itemsort to ask for a reverse sort. But in the mean time, how can I roll my own reverse sort?

stanl

Feel you would have to indicate the list items you want to sort. The WB function is char-based so in the example below not really going to sort by date with just the itemsort() function. There are,of course methods to get around treating numbers as numbers or dates as dates and possibly some RegEx, Array, or map code would help. My response is based on a generic reverse-sort holy grail and as first indicted, if you post a list, might be an easy solution.


Code (WINBATCH) Select


list="10/10/2022,01/3/2022,03/1/2023,10/5/2023,04/12/2023"
newlist = ItemSort(list, ",")
Message("List generated by ItemSort", newlist)

JTaylor

As Stan noted there are types that won't work, but that aside, use ItemSort() and then rebuild the list using a For Loop, starting from the end.  Not trying for usable code below, just to make the idea clear.

nlist = ""
list = ItemSort(list,",")
cnt = ItemCount(list,",")
For x = cnt to 1 by -1
   nlist = nlist:",":ItemExtract(x,list,",")
Next

nList = ItemRemove(1,nlist,",")


Haven't tried it but you might be able to load to an array and sort.  I think it handles some types.  Would need to look at documentation.  Arrayize() would be the place to start.

Hopefully WB will add this option.  It is something I requested as well, many years ago.

Jim

kdmoyers

Just for grins, I threw the problem at ChatGPT4.  It's a little off on syntax, but amazing nontheless.

PROMPT:
in Winbatch programming language, write a routine to reverse a sorted list A.

RESPONSE:
WinBatch is a scripting language primarily used for automating Windows tasks. Here's a simple routine to reverse a sorted list in WinBatch:

Code (winbatch) Select
; Function to reverse a sorted list A
:UserFunction ReverseList(A)
    listLength = ItemCount(A, @TAB) ; Get the length of the list
    reversedList = "" ; Initialize the reversed list

    ; Loop through the list in reverse order
    for i = listLength - 1 to 0 step -1
        element = ItemExtract(i, A, @TAB) ; Extract the i-th element
        reversedList = StrCat(reversedList, element, @TAB) ; Append the element to the reversed list
    next

    return StrTrim(reversedList, 3, @TAB) ; Remove the trailing tab and return the reversed list
:EndFunction

; Example usage
sortedList = "1@TAB2@TAB3@TAB4@TAB5"
reversedList = ReverseList(sortedList)

Message("Reversed List", StrReplace(reversedList, @TAB, ", ")) ; Display the reversed list, replacing tabs with commas


This script defines a function ReverseList() that takes a tab-separated list A as input, reverses it, and returns the reversed list. The example usage demonstrates how to use this function to reverse a sorted list and display the result.
The mind is everything; What you think, you become.

kdmoyers

I wonder where it got this odd syntax from?
like, the ":UserFunction" thing and the three parameter StrTrim function call?
The mind is everything; What you think, you become.

JTaylor

You probably need to feed it the documentation first :)

Jim

Quote from: kdmoyers on March 20, 2023, 06:27:10 AM
I wonder where it got this odd syntax from?
like, the ":UserFunction" thing and the three parameter StrTrim function call?

td

The end is nigh...

Anyway, why not load the data into an array? The ArraySort function has options for sorting direction (@Ascending, @Descending) and sort type (@Stringsort, @Logicalsort). If you need an item list, you can use the Arrayize and ArrayItemize functions to convert from a list to an array and back again.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

kdmoyers

You're right Tony, that's tough to beat for simplicity:
Code (winbatch) Select
x = arrayize(list,@tab)
arraysort(x,@descending)
newlist = arrayitemize(x, @tab)
The mind is everything; What you think, you become.

td

A date example not practical for large data sets but you should not be using lists for large data sets.

Code (winbatch) Select
list="10/10/2022,01/3/2022,03/1/2023,10/5/2023,04/12/2023"
arr = Arrayize(list, ",")
last = ArrInfo(arr, 1) - 1
; Convert to WIL time.
for i = 0 to last
   arr[i] = ObjectType("date", arr[i])
next
ArraySort(arr,@DESCENDING|@LOGICALSORT)
; Convert time back to original format
for i = 0 to last
   arr[i] = TimeFormat(arr[i], "MM/d/yyyy")
next
newlist = ArrayItemize(arr, ",")
Message("List generated by ItemSort", newlist)
exit
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

I know this is off-topic. But went back into my 2006-2009 archives. Then I used a fabricated recordset to both try to identify date <> numeric <> or text items then use the .sort method with either Ascending or Descending.

td

Database tools should be and in many cases are well-suited for sorting tasks of various data types.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Then there is .NET System.Collections  Arraylist...   but not sure if it plays nice with WB CLR :-\ :-\ :-\


EDIT:  I dredged this up from 2013. Didn't get as far as the sort() method
Code (WINBATCH) Select


;Winbatch 2013 - CLR ArrayList
;
;
;Stan Littlefield June 4, 2013
;////////////////////////////////////////////////////////////////////////////////////////////////////////


ObjectClrOption("useany","System.Net")
oList = ObjectClrNew("System.Collections.ArrayList")
oList.Add("Hello") 
oList.Add("World") 
oList.Add("!") 

cTxt="My ArrayList":@CRLF
cTxt=cTxt:"Count: ":oList.Count:@CRLF 
cTxt=cTxt:"Capacity: ":oList.Capacity:@CRLF
cTxt=cTxt:"Fixed Len?: ":oList.IsFixedSize:@CRLF 
cTxt=cTxt:"Read only?: ":oList.IsReadOnly:@CRLF
cTxt=cTxt:"Item 1: ":oList.Item(1):@CRLF
oList=0
Message("",cTxt)
Exit 

pguild

Thanks for the idea. I had no idea you could use arrays in this way.   :o
Here's a function I made along with a test.
I like to pass the delimiter to the function so I can use various delimiters in my lists.

#definefunction ReverseSort (list,delim)
  x = arrayize(list,delim)
  arraysort(x,@descending)
  List = arrayitemize(x, delim)
  Return(List)
#Endfunction

;;;;;;;;;;;;;;;;;;;;;main;;;;;;;;;;;;;;;;;;;;;;;;;;;
list = "zebra,connie,beth,able"
NewList = ReverseSort(list,",")
Pause(List,Newlist)
RETURN







Quote from: kdmoyers on March 20, 2023, 08:59:32 AM
You're right Tony, that's tough to beat for simplicity:
Code (winbatch) Select
x = arrayize(list,@tab)
arraysort(x,@descending)
newlist = arrayitemize(x, @tab)


stanl

Great! Sorry went of tangent on data types.