#MinVersion 1.10.5
uses "Console"
'---------------------------------------------------------
Type template1
'---------------------------------------------------------
'---Data
sName As Long
SValue As Word
sCount As Long
'---Fills in all the values at once!
function init(sName as long, sValue as word, sCount as long)
me.sName = sName
me.sValue = sValue
me.sCount = sCount
end function
'---Represents type as string
function to_string() as string
return strformat$("{1}{2}{3}{4}{5}", me.sName, $TAB, me.sValue, $TAB, me.sCount)
end function
End Type
'---------------------------------------------------------
Type template2
'---------------------------------------------------------
'---Data
sName As string * 20
sSurname As string * 20
lAge As Long
'---Fills in all the values at once!
function init(sName as string, sSurname as string, lAge as long)
me.sName = sName
me.sSurname = sSurname
me.lAge = lAge
end function
'---Represents type as string
function to_string() as string
return strformat$("{1}{2}{3}{4}{5}", me.sName, $TAB, me.sSurname, $TAB, me.lAge)
end function
End Type
'------------------------------------------------------------------------------
' Generic function used to sort any UDT by any UDT field name
' Function takes advance of
' - new pseudo type AnyUdt that means that UDT is determined at runtime
' - new feature that allows to determine UDT element name at runtime
' including its name between () after the point
'------------------------------------------------------------------------------
function AnyUdt_QSort(byref T() as AnyType, firstIndex as long, lastIndex as long, sFieldName as String)
local idxLow as long = firstIndex
local idxHigh as long = lastIndex
local idxMid as Long = (firstIndex + lastIndex) / 2
local lPos as Long = UDT_ElementByte(T(1).(sFieldName))
local lLen as Long = SizeOf(T(1).(sFieldName))
select case parse$(typeof(T(1).(sFieldName)), ".", 1)
case "String"
local sPivot as String = mid$(T(idxMid), lPos, lLen)
Repeat
While mid$(T(idxLow), lPos, lLen) < sPivot
idxLow += 1
Wend
While mid$(T(idxHigh), lPos, lLen) > sPivot
idxHigh -= 1
Wend
If idxLow <= idxHigh Then
SWAP T(idxLow), T(idxHigh)
idxLow += 1
idxHigh -= 1
End If
Until idxLow > idxHigh
case "Numeric"
local ePivot as ext = T(idxMid).(sFieldName)
Repeat
While T(idxLow).(sFieldName) < ePivot
idxLow += 1
Wend
While T(idxHigh).(sFieldName) > ePivot
idxHigh -= 1
Wend
If idxLow <= idxHigh Then
SWAP T(idxLow), T(idxHigh)
idxLow += 1
idxHigh -= 1
End If
Until idxLow > idxHigh
end Select
If firstIndex < idxHigh then
AnyUdt_QSort(T, firstIndex, idxHigh, sFieldName)
End If
If idxLow < lastIndex then
AnyUdt_QSort(T, idxLow, lastIndex, sFieldName)
End If
End function
'---------------------------------------------------------
printl "This script demonstrates the use of AnyType function parameter type"
printl "in conjunction with UDT dynamic element name using a string expression inside ()"
printl "for determining UDT element name."
printl "---"
printl "The same function, AnyUdt_QSort, will be used to sort 2 different UDT by different UDT field names"
printl "---"
'---------------------------------------------------------
printl "Press a key to continue" in %CCOLOR_FLIGHTRED
WaitKey
Dim i As Long
dim nElements as long = 10000
printl "Defining 2 different UDT arrays of", nElements," elements each"
Dim symbol1(nElements) As template1
Dim symbol2(nElements) As template2
printl "Filling each UDT element of the 2 UDT arrays ..."
randomize Timer
for i = 1 to nElements
symbol1(i).init(rnd(-10000, 10000), i, Rnd(1,1000))
symbol2(i).init("Name:" & format$(rnd(0, 9999),"0000"), "Surname:" & format$(i, "0000"), Rnd(1,100))
Next
printl "Done"
PrintL
String sSortByFieldName = "sCount"
printl "Start sorting first UDT by element whose name is", sSortByFieldName, Timer
AnyUdt_QSort(symbol1, 1, ubound(symbol1), sSortByFieldName)
printl "Done", Timer
printl "After Quick Sort", typeof(symbol1) + " by ." + sSortByFieldName
printl "First and last 5 elements:"
For i = 1 To nElements
'---Print first 5 elements
if i <= 5 Then
PrintL $TAB, symbol1(i).to_string()
end If
'---Print last 5 elements
if i >= nElements - 5 then
PrintL $TAB, symbol1(i).to_string()
end If
Next
PrintL
'[breakpoint] Quick Sort
sSortByFieldName = "sName"
printl "Start sorting second UDT by element whose name is", sSortByFieldName, Timer
AnyUdt_QSort(symbol2, 1, ubound(symbol2), sSortByFieldName)
printl "Done", Timer
printl "After Quick Sort", typeof(symbol2) + " by ." + sSortByFieldName
printl "First and last 5 elements:"
For i = 1 To nElements
'---Print first 5 elements
if i <= 5 Then
PrintL $TAB, symbol2(i).to_string()
end If
'---Print last 5 elements
if i >= nElements - 5 then
PrintL $TAB, symbol2(i).to_string()
end If
Next
printl
printl "All done. Press a key to end." in %CCOLOR_FLIGHTRED
WaitKey
Bookmarks