Android Question Sorting by Last Name with suffixes

Robert Valentino

Well-Known Member
Licensed User
Longtime User
I have a string of names I want to sort by last name. But don't really know where last name starts in the string

So I wrote a routine to locate the last name but ran into trouble with names with Suffixes so I added a section for it

Is there a better way to take a name (first name, middle initial, last name suffix) and flip it for sorting?

B4X:
Public  Sub SortLastName(xName As String) As String
            
            Dim Suffixes()        As String = Array As String(" jr", "jr.", " sr", " sr.", " ii", " iii", " iv", " v", " 2nd", " 3rd", " 4th")
                    
            Dim TempName        As String = xName.Trim.ToLowerCase            
            Dim Name            As String = xName.Trim
            
            Dim NameSuffix        As String

            Dim IndexLastName     As Int

            '----------------------------------------------------------------------------------------------
            '    Look for and remove any name Suffix we can find and save it for later
            '----------------------------------------------------------------------------------------------
            For Each Suffix As String In Suffixes
                If  TempName.EndsWith(Suffix) Then
                    '--------------------------------------------------------------------------------------
                    '    Name ends with the current suffix - save it for later
                    '--------------------------------------------------------------------------------------
                    NameSuffix = Name.SubString(Name.Length-Suffix.Length)
                    
                    '--------------------------------------------------------------------------------------
                    '    Remove the suffix will add on later
                    '--------------------------------------------------------------------------------------
                    Name = Name.Replace(NameSuffix, "")
                    Exit        
                End If
            Next
            
            
            '----------------------------------------------------------------------------------------------
            '  Found first occurance of space from end of name
            '----------------------------------------------------------------------------------------------
            IndexLastName = Name.LastIndexOf(" ")
            
            If  IndexLastName = -1 Then
                '------------------------------------------------------------------------------------------
                '    If we could not find where last names starts then just returned passed name
                '------------------------------------------------------------------------------------------
                Return xName                
            End If
            
            '----------------------------------------------------------------------------------------------
            '    Pull what we think is Last Name and First Name
            '----------------------------------------------------------------------------------------------
            Dim LastName     As String = $"${Name.SubString(IndexLastName + 1)}${NameSuffix}"$
            Dim FirstName     As String = Name.SubString2(0, IndexLastName)
                
            '----------------------------------------------------------------------------------------------
            '  Pad the lastname to 40 chars so when we add on firstname should make the sort right
            '----------------------------------------------------------------------------------------------
            #if Debug
            Log($"Sort Name:${PadString(LastName, 40)}, ${FirstName}"$)
            #end if
                
            Return $"${PadString(LastName, 40)}, ${FirstName}"$
End Sub

Public  Sub PadString(StringToPad As String, PadTo As Int) As String

            Dim Padder    As Int

            Dim NewString As String = StringToPad

            If  NewString.Length >= PadTo Then
                   If  NewString.Length > PadTo Then
                         NewString = NewString.SubString2(0, PadTo-3) &"..."
                   End If 
            Else
                   For Padder = NewString.Length To PadTo-1
                       NewString = NewString &" "
                   Next
            End If
 
            Return NewString
End Sub
[/code}
 
Last edited:

walt61

Active Member
Licensed User
Longtime User
I'll do both :
B4X:
Sub Process_Globals
    Type FullName (First As String, Last As String, Suffix As String)
End Sub

Sub AppStart (Args() As String)

    Dim lst As List
    lst.Initialize
    ' Note: not handling an uninitialised 'FullName' here:
    lst.Add(CreateFullName("John Smith Sr."))
    lst.Add(CreateFullName("Joe Doe"))

    lst.SortTypeCaseInsensitive("Last", True)

    Log(lst)

End Sub

Public Sub CreateFullName(xName As String) As FullName

    Dim fullName1 As FullName

    ' Remove duplicate spaces from the input
    xName = xName.Trim
    Do While xName.Contains("  ")
        xName = xName.Replace("  ", " ")
    Loop

    Dim splitName() As String = Regex.Split(" ", xName)
    If splitName.Length < 2 Then Return fullName1 ' Returning an uninitialised 'FullName' as we Expected at least 2 elements: First Name, Last Name

    fullName1.Initialize
    fullName1.First = splitName(0)
    fullName1.Last = splitName(1)
    If splitName.Length > 2 Then fullName1.Suffix = splitName(2)

    Return fullName1

End Sub

Edit: added removal of duplicate spaces from the input, and trimmed it
 
Last edited:
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
I store the string I return in a type (LastName_FirstName). But using a type only lets you sort on Last Name. So if you have John Smith, Jane Smith, Joe Smith and you sort by last name you won't necessarily get Jane Smith, Joe Smith, John Smith.

That was the reason I padded the names and stored in a Last Name First Name field of a type. NOTE: had to use underscores for this example below. Multiple spaces show as only 1 space for some reason.

Smith__________John
Smith__________Jane
Smith__________Joe

So when I sort them the sort properly. If SortType allowed concatenating field names that would probably work. Just was looking for a better way then storing multiple padded fields

Pretty much I have multiple strings for multiple sorts kind of what Erel suggested in this post: https://www.b4x.com/android/forum/t...ith-multiple-criterias-solved.119494/#content. But just seems like a waste of resources if there are a large number of items
 
Last edited:
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
I believe the padding is needed.

Take this example without spaces sorts like
Without spaces:
Sort Name:DavidsonMike
Sort Name:DavidSonny

With spaces (or in this case underscores because multiple spaces here get replaced by 1):
Sort Name:David_______Sonny
Sort Name:Davidson____Mike
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I store the string I return in a type (LastName_FirstName). But using a type only lets you sort on Last Name. So if you have John Smith, Jane Smith, Joe Smith and you sort by last name you won't necessarily get Jane Smith, Joe Smith, John Smith.
Create and use a DB.

If you want, you can create a DB in memory, rather than in a file:
B4X:
SQL1.Initialize("", ":memory:", True)

Create a table, fill it in, then search and sort as you like.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…