Results 1 to 1 of 1

Thread: UDT Sort in thinBasic 1.10.5: AnyType, any field

  1. #1
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10

    UDT Sort in thinBasic 1.10.5: AnyType, any field

    thinBasic 1.10.5, among many other new features, introduced 2 new UDT concepts:
    AnyType in script function parameter type
    the possibility to specify UDT element names by a string expression calculated at run time using () notation

    An example is better than many words.
    The following script define 2 different UDT, creates 2 different UDT arrays, uses only one function (AnyUdt_QSort) to sort the 2 UDT array variables by different UDT field names.

    UDT_Sort.PNG

    #MinVersion 1.10.5
    
    uses "Console"
     
    '---------------------------------------------------------
    Type template1
    '---------------------------------------------------------
      '---Data
      sName   As Long
      SValue  As Word
      sCount  As Long
       
      '---Fills in all the values at once!
      function init(sName as long, sValue as word, sCount as long)
        me.sName = sName
        me.sValue = sValue
        me.sCount = sCount
      end function
       
      '---Represents type as string
      function to_string() as string
        return strformat$("{1}{2}{3}{4}{5}", me.sName, $TAB, me.sValue, $TAB, me.sCount)
      end function
      
    End Type
    
    
    '---------------------------------------------------------
    Type template2
    '---------------------------------------------------------
      '---Data
      sName     As string * 20
      sSurname  As string * 20
      lAge      As Long
       
      '---Fills in all the values at once!
      function init(sName as string, sSurname as string, lAge as long)
        me.sName    = sName
        me.sSurname = sSurname
        me.lAge     = lAge
      end function
       
      '---Represents type as string
      function to_string() as string
        return strformat$("{1}{2}{3}{4}{5}", me.sName, $TAB, me.sSurname, $TAB, me.lAge)
      end function
      
    End Type
    
    
    '------------------------------------------------------------------------------
    ' Generic function used to sort any UDT by any UDT field name
    ' Function takes advance of 
    '   - new pseudo type AnyUdt that means that UDT is determined at runtime
    '   - new feature that allows to determine UDT element name at runtime
    '     including its name between () after the point
    '------------------------------------------------------------------------------
    function AnyUdt_QSort(byref T() as AnyType, firstIndex as long, lastIndex as long, sFieldName as String)
      local idxLow      as long = firstIndex
      local idxHigh     as long = lastIndex
      local idxMid      as Long = (firstIndex + lastIndex) / 2
    
    
      local lPos        as Long = UDT_ElementByte(T(1).(sFieldName))
      local lLen        as Long = SizeOf(T(1).(sFieldName))
    
    
    
    
      select case parse$(typeof(T(1).(sFieldName)), ".", 1)
        case "String"
          local sPivot      as String = mid$(T(idxMid), lPos, lLen)
    
    
          Repeat
    
    
            While mid$(T(idxLow), lPos, lLen) < sPivot
              idxLow += 1
            Wend
    
    
            While mid$(T(idxHigh), lPos, lLen) > sPivot
              idxHigh -= 1
            Wend
         
            If idxLow <= idxHigh Then
              SWAP T(idxLow), T(idxHigh)
              idxLow += 1
              idxHigh -= 1
            End If
         
          Until idxLow > idxHigh
        case "Numeric"
          local ePivot      as ext = T(idxMid).(sFieldName)
    
    
          Repeat
    
    
            While T(idxLow).(sFieldName) < ePivot
              idxLow += 1
            Wend
    
    
            While T(idxHigh).(sFieldName) > ePivot
              idxHigh -= 1
            Wend
         
            If idxLow <= idxHigh Then
              SWAP T(idxLow), T(idxHigh)
              idxLow += 1
              idxHigh -= 1
            End If
         
          Until idxLow > idxHigh
      end Select
     
      If firstIndex < idxHigh then
        AnyUdt_QSort(T, firstIndex, idxHigh, sFieldName)
      End If
     
      If idxLow < lastIndex then
        AnyUdt_QSort(T, idxLow, lastIndex, sFieldName)
      End If
      
    End function
    
    
    '---------------------------------------------------------
    printl "This script demonstrates the use of AnyType function parameter type"
    printl "in conjunction with UDT dynamic element name using a string expression inside ()"
    printl "for determining UDT element name."
    printl "---"
    printl "The same function, AnyUdt_QSort, will be used to sort 2 different UDT by different UDT field names"
    printl "---"
    '---------------------------------------------------------
    printl "Press a key to continue" in %CCOLOR_FLIGHTRED
    WaitKey
    
    
    Dim i           As Long
    dim nElements   as long = 10000
    printl "Defining 2 different UDT arrays of", nElements," elements each"
    Dim symbol1(nElements) As template1
    Dim symbol2(nElements) As template2
    
    
    printl "Filling each UDT element of the 2 UDT arrays ..." 
    randomize Timer 
    for i = 1 to nElements
      symbol1(i).init(rnd(-10000, 10000),  i, Rnd(1,1000))
      symbol2(i).init("Name:" & format$(rnd(0, 9999),"0000"),  "Surname:" & format$(i, "0000"), Rnd(1,100))
    Next
    printl "Done" 
    
    
    
    
    PrintL
    
    
    String sSortByFieldName = "sCount"
    printl "Start sorting first UDT by element whose name is", sSortByFieldName, Timer
    AnyUdt_QSort(symbol1, 1, ubound(symbol1), sSortByFieldName)
    printl "Done", Timer
    printl "After Quick Sort", typeof(symbol1) + " by ." + sSortByFieldName
    printl "First and last 5 elements:"
      For i = 1 To nElements
        '---Print first 5 elements
        if i <= 5 Then
          PrintL $TAB, symbol1(i).to_string()
        end If
        '---Print last 5 elements
        if i >= nElements - 5 then
          PrintL $TAB, symbol1(i).to_string()
        end If
        
      Next
    PrintL
    
    
    '[breakpoint] Quick Sort
    sSortByFieldName = "sName"
    printl "Start sorting second UDT by element whose name is", sSortByFieldName, Timer
    AnyUdt_QSort(symbol2, 1, ubound(symbol2), sSortByFieldName)
    printl "Done", Timer
    printl "After Quick Sort", typeof(symbol2) + " by ." + sSortByFieldName
    printl "First and last 5 elements:"
      For i = 1 To nElements
        '---Print first 5 elements
        if i <= 5 Then
          PrintL $TAB, symbol2(i).to_string()
        end If
        '---Print last 5 elements
        if i >= nElements - 5 then
          PrintL $TAB, symbol2(i).to_string()
        end If
      Next
    printl
    
    
    printl "All done. Press a key to end." in %CCOLOR_FLIGHTRED
    WaitKey
    
    Attached Files Attached Files
    Last edited by ErosOlmi; 15-10-2018 at 23:15.
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

Similar Threads

  1. Difficulties when trying to sort a custom type array
    By dco045 in forum thinBasic General
    Replies: 21
    Last Post: 20-07-2018, 09:48
  2. Array Sort - once more...
    By ReneMiner in forum Suggestions/Ideas discussions
    Replies: 3
    Last Post: 20-12-2015, 13:23
  3. Array Sort- issue
    By ReneMiner in forum Core module
    Replies: 3
    Last Post: 04-11-2015, 00:41
  4. Replacing ARRAY SORT
    By MikeTrader in forum Power Basic
    Replies: 9
    Last Post: 28-08-2009, 22:57

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •