I think PureBasic could really use sorting functions that make use of a user-defined callback function to determine the sorting order.
The functions would look as follows:
Code: Select all
SortArrayCallback(ArrayToSort(), @Callback())
SortListCallback(ListToSort(), @Callback())
The callback function would be defined as follows:
Code: Select all
Procedure.i Callback(*Greater, *Lesser)
EndProcedure
One use for this function is to sort a list by multiple criteria, like it can be done in SQL with "ORDER BY a, b, c".
Code: Select all
Structure People
Name.s
YearOfGraduation.i
EndStructure
NewList People.People()
AddElement(People())
People()\Name = "Bernard Einstein"
People()\YearOfGraduation = 1921
AddElement(People())
People()\Name = "Horst Schlämmer"
People()\YearOfGraduation = 1985
AddElement(People())
People()\Name = "Albert Einstein"
People()\YearOfGraduation = 1921
; Sort by year of graduation, sort people with same values by name
; like SQL "ORDER BY YearOfGraduation, Name"
Procedure Callback(*Greater.People, *Lesser.People)
If *Greater\YearOfGraduation > *Lesser\YearOfGraduation Or
(*Greater\YearOfGraduation = *Lesser\YearOfGraduation And *Greater\Name > *Lesser\Name)
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
SortListCallback(People(), @Callback())
Another use is to sort a list by values that are not stored in the list elements themselves, but in other memory locations that are referenced by pointers inside the elements.
Code: Select all
Structure Engine
Name.s
Thrust.d
EndStructure
Structure Plane
Name.s
*Engine.Engine
NumberOfEngines.i
EndStructure
; Engines
With Pratt.Engine
\Name = "Pratt & Whitney TF30-P-412A"
\Thrust = 68000
EndWith
With Tumanski.Engine
\Name = "Tumanski R-95Sh"
\Thrust = 40170
EndWith
; Planes
NewList Plane.Plane()
AddElement(Plane())
Plane()\Name = "Grumman F-14A"
Plane()\Engine = @Pratt
Plane()\NumberOfEngines = 2
AddElement(Plane())
Plane()\Name = "Sukhoi Su-25K"
Plane()\Engine = @Tumanski
Plane()\NumberOfEngines = 2
; Sort by total thrust
Procedure Callback(*Greater.Plane, *Lesser.Plane)
If (*Greater\Engine\Thrust * *Greater\NumberOfEngines) > (*Lesser\Engine\Thrust * *Lesser\NumberOfEngines)
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
SortListCallback(Plane(), @Callback())
Furthermore it would be useful if the sorting function accepts a *CallbackData parameter that is passed to the callback, allowing to (re-)configure the callback for different tasks, preventing the need for many different callbacks for each task.
This would look as follows:
Code: Select all
SortListCallback(ListToSort(), @Callback(), *CallbackData)
Procedure.i Callback(*Greater, *Lesser, *CallbackData)
EndProcedure
Nils