Hi I have some code that creates a string, turns it into an array, makes the array unique and then turns it back into a string. The only thing that is missing is to sort the values in ascending order. I have tried and failed can someone help me out ?
Subject: Sort a LotusScript Array in Ascending order
Hi Paul…
Here’s a little Sort function that may help out.
Function SortList (FullList , Direction) As Variant
Dim Temp As String , Change As Integer
Change = True
While Change
Change = False
For iLP = 0 To Ubound(FullList) - 1
If (FullList (iLP) > FullList (iLP + 1) And Direction = "A") Or (FullList (iLP) < FullList (iLP + 1) And Direction = "D") Then
Temp = FullList (iLP)
FullList (iLP) = FullList (iLP + 1)
FullList (iLP + 1) = Temp
Change = True
End If
Next
Wend
SortList = FullList
Subject: RE: Sort a LotusScript Array in Ascending order
That’ll work, but next to sitting around waiting for the array to sort itself, it’s the slowest way to sort. In a one-off, UI action with a very small array, you’d never notice, really, but if you use that over and over again in an agent on even moderate-sized arrays, you’d more than notice a difference if you used this function instead:
Sub shellSort(sourceArray As Variant)
Dim Lower As Integer
Dim Upper As Integer
Dim botMax As Integer
Dim i As Integer
Dim k As Integer
Dim h As Integer
Dim curVal As String
Lower = Lbound(sourceArray)
Upper = Ubound(sourceArray)
h = 1
Do
' Determine starting h
h = (3*h) + 1
Loop Until h > Upper-Lower+1
Do
h = h \ 3
botMax = Lower + h - 1
For i = botMax + 1 To Upper
curVal = sourceArray(i)
k = i
Do While sourceArray(k - h) > curVal
sourceArray(k) = sourceArray(k - h)
k = k - h
' A goto - sorry about that
If (k <= botMax) Then Exit Do
Loop
wOut:
If (k <> i) Then sourceArray(k) = curVal
Next
Loop Until h = 1
End Sub
It’s a sub, not a function, so it works on the original array rather than returning a new one. Reversing the sort is just a matter of changing the sign on the comparator – but it’s much better to build a separate sub for that than to do a case check for every comparison. If you want to feed a “direction” argument to the sub you call, hand the arguments off to a sub whose only job is to decide whether to hand the task over to the ascending or descending sort.
Thanks, Willy. I never even looked to see the String() passed in – it was just a copy-and-paste of something Nathan posted wot I happened to know was here already (he posted a Shell several times). Of course a Variant is a better idea all around – almost every native type has a valid, simple greater-than/less-than comparison. And the shadow array (or companion array) is a great addition for sorting just about anything. If you use the Set keyword, the companion can hold objects as well (in case you want to, say, sort a document collection by completed date or some such thing). I’ve seen this variation:
.
.
.
For i = botMax + 1 To Upper
curVal = sourceArray(i)
If Isobject(shadowarray(i)) Then
Set curVals = shadowarray(i)
Else
curVals = shadowarray(i)
End If
k = i
Do While sourceArray(k - h) > curVal
sourceArray(k) = sourceArray(k - h)
If Isobject(shadowarray(k-h))
Set shadowarray(k) = shadowarray(k - h)
Else
shadowarray(k) = shadowarray(k - h)
End If
k = k - h
' A goto - sorry about that
If (k <= botMax) Then Exit Do
Loop
wOut:
If (k <> i) Then sourceArray(k) = curVal : shadowarray(k) = curVals
Next
.
.
.
but the repeated Isobject check in the loop bugs the hell out of me, so I’d prefer to see three sort routines in a ShellSort script library: a vanilla, single-array sort; a shadow sort for Types or other values with a complex comparator (you calculate the comparison value once for each value instead of every time a comparison is made in the loop); and one for a shadow sort with objects. Make that six sort subroutines (an ascending and a descending version of each), plus a generic caller if you want to simplify the code monkey’s life.
Subject: RE: Sort a LotusScript Array in Ascending order
i’m a fan of the sortshell as well. Other good ones easy to code in LS are heapsort and quicksort.
Way too many bubblesort code examples out there. The only time you should ever see a bubblesort is when explaining how not to sort and the importance of using algorithms with practical worst, avg, & best case run-times.
Here is a simple ‘list sort’ using a shellsort.
Function ListSort(vl As Variant) As Variant
Dim ar$(), i%
Dim retList List As String
Forall v In vl
Redim Preserve ar$(i)
ar(i) = Listtag(v)
i = i + 1
End Forall
Call shellsort(ar)
For i = Lbound(ar) To Ubound(ar)
retList(ar(i)) = vl(ar(i))
Next
ListSort = retList
It’s fast and furious, at the cost of memory, which is abundant these days. I’ve used quicksort for nearly a decade to sort up to thousands of web search results in nearly unnoticeable time. My particular code has a recursion limit that I’ve personally never hit, but installed way back in R4 days when memory was more scarce. Better to abort the sort than crash the server, I thought. (grin)
The code is out there because that’s where I got it, then streamlined it. For instance the code I scammed did tons of unnecessary pivots, which I fixed - it sorted great but wasted time. This was considerably quicker than coding it myself.
Subject: RE: Search the web for a quicksort routine…
The problem with a quicksort isn’t the overall memory it takes (which, as you pointed out, is unimaginably cheap to those of us who remember buying 1x256 bit chips in bunches of eight at something like two hundred bucks), but stack space, which is a language limitation. If you want to hit the limit, all you need is a moderate-sized array that’s almost (or completely) sorted already – that’s the worst-case scenario for a quicksort. I was an avid QS user before I started working with Notes, and found the stack problem early trying to insert new values into a previously-sorted collection. There are “iterative” quicksorts to be found on the web that get around the problem (and they’re not really iterative, they just maintain their own call stack in runtime memory rather than using the language call stack).
Shell is actually faster than quicksort on average on typical Notes-sized collections (arrays with integer-sized indices), and it’s WAY faster if the data is already sorted or nearly sorted. The version I posted is not optimal, it’s a paste of something Nathan Freeman posted when N&D 6 was a puppy. (The optimal interval size is unknown, but the best average-case sequence of intervals found so far is the Sedgwick sequence).
Subject: Sort a LotusScript Array in Ascending order
You must pass a well formatted string array! I have made a working example for you.
Sub Initialize
Dim col (1 To 4 )As Variant ' can be also String
Dim result As Variant
Dim m2 As String
Dim r1 As String
col(1) = "Z"
col(2) = "x"
col(3) = "a"
col(4) = "c"
Forall x In col
r1 = r1 + {'} + x + {'} + {:}
End Forall
r1= Left(r1, Len(r1) -1 )
m2 = {@sort( } + r1 + { ;[ASCENDING]) }
result = Evaluate(m2)