SortStringArraySpecial()

Share your advanced PureBasic knowledge/code with the community.
Little John
Addict
Addict
Posts: 4519
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

SortStringArraySpecial()

Post by Little John »

Special handling of empty strings when sorting a string array. For details see comments in the code.
There was a request for this.

Code: Select all

; tested with PB 5.71 LTS

EnableExplicit


Procedure SortStringArraySpecial (Array a$(1), options.i, first.i=0, last.i=-1)
   ; After (a range of) a string array has been sorted ascending with PB's built-in function,
   ; empty strings are at the *beginning* of the array (or of the chosen range).
   ; When sorting descending, empty strings are put at the *end*.
   ;
   ; This procedure does almost the same as PB's built-in function SortArray(), but
   ; - puts empty strings at the end when sorting ascending
   ; - puts empty strings at the beginning when sorting descending
   Protected.i i, offset
   
   If last = -1
      last = ArraySize(a$())
   EndIf   
   
   SortArray(a$(), options, first, last)
   
   If options & #PB_Sort_Descending
      ; Empty strings are at the end of the sorted range.
      ; Now put them at the beginning of that range.
      
      ; Count number of empty strings at the end.
      For i = last To first Step -1
         If Asc(a$(i)) <> ''
            Break
         EndIf   
      Next   
      offset = last - i
      
      If offset > 0 And offset < last-first+1
         ; Move non-empty elements towards the end
         For i = last To first+offset Step -1
            a$(i) = a$(i-offset)
         Next
         
         ; Set elements at the beginning of the range to ""
         For i = first+offset-1 To first Step -1
            a$(i) = ""
         Next
      EndIf
      
   Else   
      ; Empty strings are at the beginning of the sorted range.
      ; Now put them at the end of that range.
      
      ; Count number of empty strings at the beginning.
      For i = first To last
         If Asc(a$(i)) <> ''
            Break
         EndIf   
      Next   
      offset = i - first
      
      If offset > 0 And offset < last-first+1
         ; Move non-empty elements towards the beginning
         For i = first To last-offset
            a$(i) = a$(i+offset)
         Next
         
         ; Set elements at the end of the range to ""
         For i = last-offset+1 To last
            a$(i) = ""
         Next   
      EndIf   
   EndIf   
EndProcedure


; -- Demo
Define.i i, lastElement = 6
Dim a$(lastElement)
Dim b$(lastElement)

; Create original array
a$(1) = "b"
a$(3) = "a"
a$(5) = "d"
a$(6) = "c"

Debug "Sorted ascending with PB's built-in function:"
CopyArray(a$(), b$())
SortArray(b$(), #PB_Sort_Ascending)
For i = 0 To lastElement
   Debug "'" + b$(i) + "'"
Next   

Debug ""
Debug "Sorted ascending with SortStringArraySpecial():"
CopyArray(a$(), b$())
SortStringArraySpecial(b$(), #PB_Sort_Ascending)
For i = 0 To lastElement
   Debug "'" + b$(i) + "'"
Next   

Debug ""
Debug "Sorted descending with PB's built-in function:"
CopyArray(a$(), b$())
SortArray(b$(), #PB_Sort_Descending)
For i = 0 To lastElement
   Debug "'" + b$(i) + "'"
Next   

Debug ""
Debug "Sorted descending with SortStringArraySpecial():"
CopyArray(a$(), b$())
SortStringArraySpecial(b$(), #PB_Sort_Descending)
For i = 0 To lastElement
   Debug "'" + b$(i) + "'"
Next