Android Tutorial [B4X] Sophisticated sorting with B4XComparatorSort

B4XCollections v1.13 includes a new sorting feature named B4XComparatorSort.
This feature allows sorting using a custom comparator class.
The comparator class is a class that you create and it should include a sub with the following signature:
B4X:
'Return a positive number if o1 greater than o2 (=o1 comes after o2), 0 if o1 equals to o2 and a negative number if o1 smaller than o2.
Public Sub Compare (o1 As Object, o2 As Object) As Int

For example, if we want to sort a list of strings based on the strings lengths:
B4X:
'Return a positive number if o1 greater than o2 (=o1 comes after o2), 0 if o1 equals to o2 and a negative number if o1 smaller than o2.
Public Sub Compare (o1 As Object, o2 As Object) As Int
 Dim s1 As String = o1
 Dim s2 As String = o2
 If s1.Length > s2.Length Then
  Return 1
 Else If s1.Length < s2.Length Then
  Return -1
 Else
  Return 0
 End If
'or:
 Return s1.Length - s2.Length

This allows us to sort lists using all kinds of sophisticated ordering.
Attached is an example of sorting "person" records. The fields are:
B4X:
Type Person (Name As String, Age As Int, Status As String)

We want to first list the employees, sorted by their names and then sorted by their ages.

B4X:
Public Sub Compare (o1 As Object, o2 As Object) As Int
    Dim p1 As Person = o1
    Dim p2 As Person = o2
    If p1.Status = "Employee" And p2.Status <> "Employee" Then Return -1
    If p2.Status = "Employee" And p1.Status <> "Employee" Then Return 1
    If p1.Name = p2.Name Then
        If p1.Age > p2.Age Then Return 1
        If p1.Age < p2.Age Then Return - 1
    End If
    Return p1.Name.CompareTo(p2.Name)
End Sub

1646731240386.png


Note that there is relatively a large difference in the performance of this sort feature between debug mode and release mode.
 

Attachments

  • Project.zip
    15.5 KB · Views: 326
Last edited:

Mahares

Expert
Licensed User
Longtime User
If I can acchieve the same result with a little table query. What am I missing in using this sophisticated sort:
Is the object to sort only those that have a status 'Employee' and leave the rest of the records untouched without disturbing their order.
B4X:
strQuery =$"SELECT
    * FROM table1 WHERE Status = 'Employee'
    UNION
    SELECT * FROM table1 WHERE Status = 'Contractor'
    ORDER BY Status DESC"$
'    James,64,Employee
'    Susan,36,Employee
'    James,33,Contractor
'    Robert,55,Contractor
'    Suzan,36,Contractor
'    Suzan,38,Contractor
Or even with a simpler query not involving UNION
 

Sandman

Expert
Licensed User
Longtime User
What am I missing in using this sophisticated sort
You're comparing two different things:
  1. The B4XComparatorSort is a method to sort data in B4XCollections.
  2. Your example is a method to sort data in an SQL database.

Both are awesome, but they are not the same.
 

Mahares

Expert
Licensed User
Longtime User
Both are awesome, but they are not the same.
So what is the benefit of that sort in the given example. What is the real world application.
It is better to ask the questions by opening new threads; this is a tutorial.
You are corrrect. The only reason I posted here is because the tutorial is new and it would not ring a bell with most members yet if I referenced: B4XComparatorSort. @Erel can choose to delete these posts afterwards.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
If I can acchieve the same result with a little table query. What am I missing in using this sophisticated sort:
Is the object to sort only those that have a status 'Employee' and leave the rest of the records untouched without disturbing their order.
1. This is just an example.
2. No. The purpose was to list the "employees" first and then the other statuses. Your code will not work for this case.
3. As @Sandman wrote, you are comparing two different things. The data to sort doesn't always come from a database.
 
Top