Android Question Trying to use comparator sort

warayTek

Member
Licensed User
Hi everyone! I need to sort the following items
from:
B4X:
sn, 1004
sn, 1003
sn, 1002
sn, 1001
sn, 1000
ns, 1014
ns, 1012
ns, 1011
ns, 1010
to
B4X:
sn, 1000
sn, 1001
sn, 1002
sn, 1003
sn, 1004
ns, 1010
ns, 1011
ns, 1012
ns, 1014
FIrst is must look for "sn" (priority) and sort the number of part in ascending. (The same with "ns").
The code below is what I am trying to work on.
B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Type Person (sn As String, number As Int)
    Private ComparatorSort As B4XComparatorSort
    Private PersonComparator1 As PersonComparator
    Private Persons As List
    Private CustomListView1 As CustomListView
End Sub

Public Sub Initialize
    ComparatorSort.Initialize
    PersonComparator1.Initialize
    Persons.Initialize
    Persons.Add(CreatePerson("sn", "1001"))
    Persons.Add(CreatePerson("sn", "1002"))
    Persons.Add(CreatePerson("sn", "1004"))
    Persons.Add(CreatePerson("sn", "1003"))
    Persons.Add(CreatePerson("sn", "1000"))
    Persons.Add(CreatePerson("ns", "1014"))
    Persons.Add(CreatePerson("ns", "1010"))
    Persons.Add(CreatePerson("ns", "1011"))
    Persons.Add(CreatePerson("ns", "1012"))
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    ComparatorSort.Sort(Persons, PersonComparator1)
    For Each p As Person In Persons
        'CustomListView1.AddTextItem($"${p.sn}, ${p.Status}"$, p)
        Log($"${p.sn}, ${p.number}"$)
    Next
End Sub

Public Sub CreatePerson (sn As String, number As Int) As Person
    Dim t1 As Person
    t1.Initialize
    t1.sn = sn
    t1.number = number
    Return t1
End Sub
To be honest I don't understand this code
B4X:
Public Sub Compare (o1 As Object, o2 As Object) As Int
    Dim p1 As Person = o1
    Dim p2 As Person = o2
    If p1.sn = "sn" And p2.sn <> "sn" Then Return -1
    If p2.sn = "sn" And p1.sn <> "sn" Then Return 1
    If p1.number > p2.number Then
        If p1.number > p2.number Then Return -1
        If p1.number < p2.number Then Return 1
    End If
    Return p1.sn.CompareTo(p2.sn)
End Sub
I appreciate any help and the time.
 

Daestrum

Expert
Licensed User
Longtime User
Taking a simpler example comparing 'a' to 'b'

(The accepted normal returns for a comparitor are)

if a < b return -1
if a > b return 1
if a = b return 0

because you have 2 parts to your test 'sn' and 'number' you have more tests to do

sn1 < sn2 , sn1 > sn2 and sn1 = sn2
number1 < number2 , number1 > number2 and number1 = number2

which all boils down to

if compare return 0 then they are equal
if compare <> 0 they are unequal

whether you need to know if a < b or a > b depends on your use, as you are sorting then you need to know if object(a) is less or greater or equal to object(b).
 
Upvote 0

emexes

Expert
Licensed User
If they're all 2-character priorities and 4-character numbers then you could sort them as 6-character strings.

Is it for a multi-stream queuing system? If you're only dealing with smallish quantities and simply looking for the next (lowest-valued?) item, then a sequential pass through the list would be fast enough.
 
Upvote 0

emexes

Expert
Licensed User
To be honest I don't understand this code
B4X:
Public Sub Compare (o1 As Object, o2 As Object) As Int
    Dim p1 As Person = o1
    Dim p2 As Person = o2
    If p1.sn = "sn" And p2.sn <> "sn" Then Return -1
    If p2.sn = "sn" And p1.sn <> "sn" Then Return 1
    If p1.number > p2.number Then
        If p1.number > p2.number Then Return -1
        If p1.number < p2.number Then Return 1
    End If
    Return p1.sn.CompareTo(p2.sn)
End Sub

A comparator routine is used by a general sort routine to compare two of whatever is being sorted (in this case: two Persons) and returns:

+1 if they are in the correct order, or
-1 if they are not in the correct order (ie the sort routine needs to swap them around), or
0 if they are the same

I agree that the last line of that routine is a bit cryptic: it seems to be allowing for priorities other than just "sn" and "ns".
 
Upvote 0

teddybear

Well-Known Member
Licensed User
Try this code
B4X:
Public Sub Compare (o1 As Object, o2 As Object) As Int
    Dim p1 As Person = o1
    Dim p2 As Person = o2
  
    If p1.sn.CompareTo(p2.sn) < 0 Then Return 1
    If p1.sn.CompareTo(p2.sn) > 0 Then Return -1
    If p1.number > p2.number Then Return 1
    If p1.number < p2.number Then Return -1
    return 0
  
End Sub
 
Last edited:
Upvote 0
Top