Sort a LotusScript Array in Ascending order

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 ?

Dim column1 As String

column1 = column1 + viewEntryDoc.gpProjOrProg(0) + “;”

Dim column1v As Variant

Dim semiColonDelim As String

semiColonDelim = “;”

column1v = Split(column1,semiColonDelim)

Dim uColumn1v As Variant

uColumn1v = Arrayunique(column1v,0)

column1 = Join(uColumn1v,“;”)

This provides me with a string separated by semi colons that I then use further down the line. I have tried to implement an

@evaluate(@sort(column1;[ASCENDING]))

but I can’t get it to work, can someone tweak what I’ve got so that the string at the end is in ascending order and still split by semi-colons?

Thanks

Paul

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

End Function

You can call it like this:

uColumn1v = SortList(uColumn1v,“A”)

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.

Subject: -

Subject: RE: Shellsort variation

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

End Function

Subject: Search the web for a quicksort routine…

  • 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.

  • Ah. My comment block says where I got it:

http://www.itkey.com/itkey/home.nsf/0906301eff1c9c78422567250074d84a/download_quicksort

Hope this helps…

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: Interesting! Thanks for the info…

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) 

End Sub