It is currently Fri Aug 14, 2020 12:16 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Index for Maps/Lists/Array [Updated]
PostPosted: Wed Nov 13, 2019 6:33 am 
Offline
Enthusiast
Enthusiast

Joined: Fri Jul 14, 2006 8:53 pm
Posts: 692
Location: Malta
; =======================================================================
; Index Maker for Maps V3.1
; -------------------------
;
; Have you ever wanted to browse your Maps in some form of order?
; Now you can!
; IndexMap can create indexes for your Maps and you supply the sorting function (don't worry its easy!)
; Multiple indexes (as many as you like) can be added to the same Map; its important you use the same group when having mu
; group when having multiple indexes on same Map; and use DIFFERENT groups for different Maps
;
; Share and use freely
;
; Code adapted by KingLestat
; Original code author: An older version of me + scrounging
; Mar/2018
; Updated Nov/2019
;
; May/2020
; Rewrite
;
; - Discovered that my FastDel was only a FastBug!
; - Without groups, when deleting an element it would remain in other indexes
; - Added search function
;
; =========================

Support files (text files for examples)
http://sen3.net/files/textfiles.7z

Code:

; =======================================================================
; Index Maker for Maps V3.1
; -------------------------
;
; Have you ever wanted to browse your Maps in some form of order?
; Now you can!
; IndexMap can create indexes for your Maps and you supply the sorting function (don't worry its easy!)
; Multiple indexes (as many as you like) can be added to the same Map; its important you use the same group when having mu
; group when having multiple indexes on same Map; and use DIFFERENT groups for different Maps
;
; Share and use freely
;
; Code adapted by KingLestat
; Original code author: An older version of me + scrounging
; Mar/2018
; Updated Nov/2019
;
; May/2020
; Rewrite
;
; - Discovered that my FastDel was only a FastBug!
; - Without groups, when deleting an element it would remain in other indexes
; - Added search function
;
; =======================================================================

DeclareModule IndexMap
     
   Prototype           CompareFN( *e1, *e2 )
   
   Declare             ndxmapCreateIndex( IndexName.s, GroupName.s, fnCompare.CompareFN, ArSize = 0 )
   Declare             ndxmapAdd( *p )
   Declare             ndxmapDelete( GroupName.s, *p )
   Declare             ndxmapClear( groupname.s )
   Declare              ndxmapSearch( *find, bExact = 0 )

    EnableExplicit

   ; ======================================================================================================
   ;- Public Constants
   ; ======================================================================================================
   CompilerIf Not Defined( PB_Compiler_Unicode, #PB_Constant )
      #PB_Compiler_Unicode       = #True
      #PB_Compiler_Thread        = #True
      #SB_Compiler_SpiderBasic   = 230
   CompilerEndIf

   Enumeration
      #NDXMAP_RESET        = 0
      #NDXMAP_FIRST        = 1
      #NDXMAP_LAST         = 2
      #NDXMAP_PREV         = 3
      #NDXMAP_NEXT         = 4
      #NDXMAP_SIZE         = 5
   EndEnumeration
   
   #NDXMAP_STANDARD        = 16033
   #NDXMAP_MEDIUM          = 34157
   #NDXMAP_LARGE           = 68891
   #NDXMAP_SMALL           = 757
   #NDXMAP_EXACT           = 1

   #NDXMAP_PRIME           = #NDXMAP_LARGE
   
; ======================================================================================================
;- Public Structures
; ======================================================================================================

   Structure stIndexDetails
      Name.s
      Group.s
      nCount.l
      nSize.l
      nGrow.l
      nPos.l
      fnCompare.CompareFN
      Array arIndex.l(0)
   EndStructure
   
; ======================================================================================================
;- Public Macros
; ======================================================================================================
   
   Macro                ndxmapSetNDX( indexname )
      FindMapElement( mapIndexMap(), indexname )
   EndMacro
   
   Macro                ndxmapChange( newpos, value )
      Select newpos

         Case #NDXMAP_FIRST
            mapIndexMap()\nPos = 0
            value = mapIndexMap()\arIndex(0)
           
         Case #NDXMAP_LAST
            mapIndexMap()\nPos = mapIndexMap()\nCount - 1
            value = mapIndexMap()\arIndex(mapIndexMap()\nPos)
           
         Case #NDXMAP_NEXT
            If value < (mapIndexMap()\nCount - 1)
               mapIndexMap()\nPos + 1
               value = mapIndexMap()\arIndex(mapIndexMap()\nPos)
            Else
               value = 0
            EndIf
         Case #NDXMAP_PREV
            If mapIndexMap()\nPos > 0
               mapIndexMap()\nPos - 1
               value = mapIndexMap()\arIndex(mapIndexMap()\nPos)
            Else
               value = 0
            EndIf
           
         Case #NDXMAP_SIZE
            value = mapIndexMap()\nCount
         
      EndSelect
   EndMacro

   ; =====================================================================================
   ;- Public Globals
   ; =====================================================================================
     
   Global NewMap        mapIndexMap.stIndexDetails(127)
     
EndDeclareModule

Module IndexMap
   
   ; =====================================================================================
   ;- Private Macros
   ; =====================================================================================

   ; =====================================================================================
   ;- Private Structures
   ; =====================================================================================

;- to remove
Structure stTest
   sText.s
   iNum.q
   dTest.d
EndStructure

   ; =====================================================================================
   ;- Module Functions
   ; =====================================================================================
   ; IndexName - A unique name to identify index
   ; GroupName - Used in deletion; when creating multiple indexes for same map, all keys for all indexes are deleted
   ; fnCompare - A Procedure which takes 2 elements of the types you want to keep sorted
   ; ArSize    - This keeps a pointer every [SplitSize] elements to make searching faster ( 1 << Search << (DataSet / SplitSize + ~ ) + SplitSize + 1 )
   ; FastDel   - This allows for fast deletions; useful withg large datasets (at a cost of extra overhead when adding + memort consumption )

   Procedure            ndxmapCreateIndex( IndexName.s, GroupName.s, fnCompare.CompareFN, ArSize = 0 )
      Protected         szGroup.s = LCase( GroupName )
     
      If FindMapElement( mapIndexMap(), IndexName )
         ProcedureReturn -1
      EndIf
     
      If ArSize <= 0    : ArSize = 1000  : EndIf
     
      AddMapElement( mapIndexMap(), IndexName )
      With mapIndexMap()
         \fnCompare     = fnCompare
         \Name          = IndexName
         \Group         = szGroup
         \nSize         = ArSize
         \nGrow         = ArSize >> 1
      EndWith

      ReDim mapIndexMap()\arIndex(ArSize)
     
   EndProcedure
   
   Procedure            ndxmapAdd( *p )
      Protected         iLow.i, iHigh.i, iMid.i
      Protected         flag, res, i
     
      If mapIndexMap()\nCount > 0
         iHigh = mapIndexMap()\nCount
         
         While iLow  <  iHigh
            If mapIndexMap()\fnCompare( *p,  mapIndexMap()\arIndex( iLow ) ) <= 0
               Break
            ElseIf mapIndexMap()\fnCompare( *p,  mapIndexMap()\arIndex( iHigh - 1 ) ) >= 0
               iLow  =  iHigh
               Break
            Else
               iMid  =  (iLow  +  iHigh)  >>  1
            EndIf
           
            res = mapIndexMap()\fnCompare( *p, mapIndexMap()\arIndex( iMid ) )
           
            If res = 0
               iLow = iMid
               Break
            ElseIf res < 0
               iHigh  =  iMid
            Else
               iLow  =  iMid  +  1
            EndIf
         Wend

         MoveMemory( @mapIndexMap()\arIndex( iLow ), @mapIndexMap()\arIndex( iLow + 1 ), @mapIndexMap()\arIndex( mapIndexMap()\nCount ) - @mapIndexMap()\arIndex( iLow ) )
      EndIf
     
      mapIndexMap()\arIndex( iLow )  = *p
      mapIndexMap()\nCount + 1
     
      If mapIndexMap()\nCount  >  mapIndexMap()\nSize
          mapIndexMap()\nSize + mapIndexMap()\nGrow
          ReDim mapIndexMap()\arIndex( mapIndexMap()\nSize )
      EndIf

   EndProcedure
   
   Procedure            ndxmapDelete( group.s, *p )
      Protected         i, j, *ptr, flag
      Protected NewList llDelete()

      group = LCase(group)
     
      ForEach mapIndexMap()
         If mapIndexMap()\Group = group
            j = 0
            ClearList( llDelete() )
         
            For i = 0 To mapIndexMap()\nCount - 1
               If *p = mapIndexMap()\arIndex(i)
                  AddElement( llDelete() )
                  llDelete() = i - j
                  j + 1
                  Break
               EndIf
            Next
           
            ForEach llDelete()
               i = llDelete()
               MoveMemory( @mapIndexMap()\arIndex( i + 1 ), @mapIndexMap()\arIndex( i ), @mapIndexMap()\arIndex( mapIndexMap()\nCount ) - @mapIndexMap()\arIndex( i + 1 ) )
               mapIndexMap()\nCount - 1
            Next
         EndIf
      Next
         
   EndProcedure
   
   Procedure            ndxmapClear( groupname.s )
     
      groupname = LCase( groupname )
     
      ForEach mapIndexMap()
         If mapIndexMap()\group = groupname
            ReDim mapIndexMap()\arIndex( 0 )
            DeleteMapElement( mapIndexMap() )
         EndIf
      Next

   EndProcedure

   Procedure            ndxmapSearch( *find, bExact = 0 )
      Protected         iLow.i, iHigh.i, iMid.i
      Protected         found, res
     
      If mapIndexMap()\nCount > 0
         iHigh = mapIndexMap()\nCount
         
         While iLow  <  iHigh
            res = mapIndexMap()\fnCompare( *find,  mapIndexMap()\arIndex( iLow ) )
         
            If res = 0
               found = mapIndexMap()\arIndex( iLow )
               Break
            ElseIf res < 0
               If bExact
                  found = 0
               Else
                  found = mapIndexMap()\arIndex( iLow )
               EndIf
               Break
            ElseIf mapIndexMap()\fnCompare( *find,  mapIndexMap()\arIndex( iHigh - 1 ) ) > 0
               If bExact
                  found = 0
               Else
                  found = mapIndexMap()\arIndex( iHigh )
               EndIf
               Break
            Else
               iMid  =  (iLow  +  iHigh)  >>  1
            EndIf
           
            res = mapIndexMap()\fnCompare( *find, mapIndexMap()\arIndex( iMid ) )
           
            If res = 0
               found = mapIndexMap()\arIndex( iMid )
               Break
            ElseIf res < 0
               iHigh  =  iMid
            Else
               iLow  =  iMid  +  1
            EndIf
         Wend
      EndIf
   
      ProcedureReturn found

   EndProcedure
   
EndModule

; ======================================================================================================
;- End Index Module
; ======================================================================================================

CompilerIf #PB_Compiler_IsMainFile

   CompilerIf #PB_Compiler_Debugger = #False
      MessageRequester( "Error",  "Switch Debugger on to see the demo.", #PB_MessageRequester_Error )
      End
   CompilerEndIf

;------------------------
;- Test Code
;------------------------

#MaxSize = 60

UseModule   IndexMap

Structure stTest
   sText.s
   iNum.q
   dTest.d
EndStructure


Global NewMap mapTest.stTest(#MaxSize)
Global Dim    arString.s(800)
   
;RandomSeed(1971)


Macro             LText( textstr )
   "] Txt="  +  LSet( textstr, 40 )
EndMacro

Macro             ListData( indexname, extra )

   Debug "==[ " + indexname + extra + " ]===================================="
   ndxmapSetNDX( indexname )

   ndxmapChange( #NDXMAP_SIZE, total )
   
   For i = 0 To total - 1
      *p = mapIndexMap()\arIndex(i)
      If *p
         Debug "["  +  RSet( Str(i + 1), 3 )  +  LText( *p\sText )  +  " ["  +  Str( *p\iNum )  +  "] --> "  +  StrD( *p\dTest, 2 )
      Else
         Debug "["  +  RSet( Str(i + 1), 3 )  +  "] <NULL>"
      EndIf
   Next
   
   Debug "Size: " + Str( total )
   
EndMacro

Macro                   FindMyString( searchtxt )
   Debug "==[ Find -->" + searchtxt  + " ]===================================="

   find\sText = searchtxt
   *ptr = ndxmapSearch( @find, #NDXMAP_EXACT )
   
   If *ptr
      Debug "Exact match found for [" + find\sText + "]"
   Else
      *p = ndxmapSearch( @find )
     
      If *p
     
         Debug "Closest match for [" + find\sText + "] is [" + *p\sText + "]"
      EndIf
   EndIf
EndMacro

Procedure               ReadTextData()
   Protected            f, i, format
   Protected            name.s

   f = ReadFile( #PB_Any, "names.txt" )
   format = ReadStringFormat( f )
   i = 0
   
   While Not Eof(f)
      name = Trim( ReadString( f, format ) )
      If name > ""
         arString(i) = name
         i + 1
      EndIf
   Wend
   
   CloseFile( f )
   ReDim arString(i)
   RandomizeArray( arString() )
   
   ProcedureReturn i
EndProcedure

Procedure         CompareInt( *p1.stTest, *p2.stTest )   
   ProcedureReturn *p1\iNum - *p2\iNum
EndProcedure


Procedure         CompareDouble( *p1.stTest, *p2.stTest )
     
   If *p1\dTest < *p2\dTest
      ProcedureReturn -1
   ElseIf *p1\dTest > *p2\dTest
      ProcedureReturn 1
   EndIf   
   
   ProcedureReturn 0
EndProcedure

Procedure         CompareString( *p1.stTest, *p2.stTest )
   
   s1.s = LCase( *p1\sText )
   s2.s = LCase( *p2\sText )
   
   If s1 < s2
      ProcedureReturn -1
   ElseIf s1 > s2
      ProcedureReturn 1
   EndIf   
   
   ProcedureReturn 0
EndProcedure

   Define   *ptr, *p.stTest, sTookString.s
   Define   i, j, total
   Define   l
   Define   find.stTest

   ndxmapCreateIndex( "DoubleFull", "test", @CompareDouble(), 50 )
   ndxmapCreateIndex( "String", "test", @CompareString(), 50 )
   ndxmapCreateIndex( "Integer", "test", @CompareInt(), 50 )
   ndxmapCreateIndex( "Alternate", "test", @CompareString(), 50 )  ; Only 50% of the dataset used
   l = ReadTextData() - 1
   
   Debug "==[As Created]===================================="
   
   For iIndex  =  0 To #MaxSize - 1
      *ptr  =  AddMapElement( mapTest(), "Key-"  +  Str(iIndex + 1) )
     
      j = Random( l )
      mapTest()\sText   = LSet( arString(j), 35 )
      mapTest()\iNum    =  Random( 499, 10 )
      mapTest()\dTest   = Random(10000, 10)  /  Random(1000, 100)   
     
      Debug "["  +  Str(iIndex)  +  LText( mapTest()\sText )  +  " ["  +  Str( mapTest()\iNum )  +  "] --> "  +  StrD( mapTest()\dTest, 2 )
     
      ndxmapSetNDX( "DoubleFull" )
      ndxmapAdd( *ptr )
     
      ndxmapSetNDX( "String" )
      ndxmapAdd( *ptr )
     
      ndxmapSetNDX( "Integer" )
      ndxmapAdd( *ptr )
     
      If Mod( iIndex + 1, 2 )
         ndxmapSetNDX( "Alternate" )
         ndxmapAdd( *ptr )
      EndIf
   Next
   
   ListData( "DoubleFull", "" )
   ListData( "String", "" )
   ListData( "Alternate", "" )
   ListData( "Integer", "" )
 
   Debug "==[Deleting some entries]===================================="
 
   iIndex = 1
   j = 0
   
   ForEach mapTest()
      If Mod( iIndex, Random(7,4) ) = 0
         j + 1
         ndxmapDelete( "test", @mapTest() )
         
         Debug "DEL->" + RSet( Str( iIndex ), 2  ) + "  " + LText( mapTest()\sText )  +  StrD( mapTest()\dTest, 2 )
         DeleteMapElement( mapTest() )
      EndIf   
      iIndex + 1
   Next
   
   Debug ""
   Debug "Total deleted: " + Str(j)
   Debug ""
   
   ListData( "Alternate", " (Deleted)" )
   ListData( "DoubleFull", " (Deleted)" )
   ListData( "String", " (Deleted)" )
   ListData( "Integer", " (Deleted)" )
   
   ndxmapSetNDX( "String" )
   
   FindMyString( "Kafka" )
   FindMyString( "God" )
   FindMyString( "Loki" )
   FindMyString( "Nemo" )
   FindMyString( "Napoleon" )
   
CompilerEndIf


_________________
I may not help with your coding
Just ask about mental issues!

http://www.lulu.com/spotlight/kingwolf
http://www.sen3.net


Last edited by kinglestat on Tue May 12, 2020 1:36 am, edited 3 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Index HashTables
PostPosted: Wed Nov 13, 2019 1:55 pm 
Offline
Addict
Addict
User avatar

Joined: Sat Apr 26, 2003 2:15 pm
Posts: 889
Location: Cuernavaca, Mexico
Thanks kinglestat

Looks like you and said were working on this about 18 months ago. :)

https://www.purebasic.fr/english/viewtopic.php?p=519564#p519564

_________________
- It was too lonely at the top.

Current Machine: Win 10 Pro 64-bit, Dual Xeon E5-2670, 64 gigs ram, Geforce GTX 1660 Ti w/6 gigs ram


Top
 Profile  
Reply with quote  
 Post subject: Re: Index HashTables
PostPosted: Wed Nov 13, 2019 2:33 pm 
Offline
Enthusiast
Enthusiast

Joined: Fri Jul 14, 2006 8:53 pm
Posts: 692
Location: Malta
This definitely proves that after 20 years I still don't know how to use the 'net :(
Thanks blue

And I was the original author? I thought the code was too elegant for it to be mine

_________________
I may not help with your coding
Just ask about mental issues!

http://www.lulu.com/spotlight/kingwolf
http://www.sen3.net


Top
 Profile  
Reply with quote  
 Post subject: Re: Index for Maps [Updated]
PostPosted: Fri May 08, 2020 12:27 pm 
Offline
Enthusiast
Enthusiast

Joined: Fri Jul 14, 2006 8:53 pm
Posts: 692
Location: Malta
Example 2:

Code:

; ===============================
; Demo 2 for Index Maker for Maps
; -------------------------------

EnableExplicit

CompilerIf #PB_Compiler_Debugger = #True
   MessageRequester( "Error",  "Switch Debugger off to run this demo.", #PB_MessageRequester_Error )
   End
CompilerEndIf

; =====================================================================================
;- Constants
; =====================================================================================
 
Enumeration
   #MainWindow
   #BtnExit
   #BtnLoad
   #BtnSearch
   #StrFind
   #EdFind
   #LVResults
   #CBFastDel
EndEnumeration

XIncludeFile "./indexmapV14.pbi"

UseModule IndexMap

; =====================================================================================
;- Structures
; =====================================================================================
 
Structure stS
   city.s
   size.l
   spc.l
EndStructure

; =====================================================================================
;- Macros (only for debug)
; =====================================================================================
 
Macro             ListData( text )
   Debug "==[ " + text + " ]===================================="
   ndxmapChangeIndex( text )
   i = 0
   
   ForEach mapIndexMap()\llIndex()
      i + 1
      *p = mapIndexMap()\llIndex()
      Debug "["  +  RSet( Str(i), 5 )  +  "] " + LSet( *p\city, 30 )  + ", " +  Str( *p\size )  +  ", " +  Str( *p\spc )
   Next
   
   Debug "Size: " + Str( ListSize( mapIndexMap()\llIndex() ) )

EndMacro

; =====================================================================================
;- Globals
; =====================================================================================

Global NewMap     mapCities.stS(50000)
Global            szTitle.s = "MapIndex Demo 2"

; =====================================================================================
;- Procedure Declare
; =====================================================================================

Declare           Compare1( *p1.sts, *p2.sts )
Declare           Compare2( *p1.sts, *p2.sts )
Declare           Compare3( *p1.sts, *p2.sts )

; =====================================================================================
;- Procedures
; =====================================================================================

Procedure         LoadFile( file.s, FastDel )
   Protected      tload, tdel, tmap
   Protected      recs1, recs2
   Protected      i, f, t,size, spc, format, flag
   Protected.s    line, msg
   Protected.stS  *p
   
   ndxmapClear( "cities" )
   ClearMap( mapCities() )
   
   If FindString( file, "cities" )
      ndxmapCreateIndex( "Alphabetic", "cities", @Compare1(), 80000 )
      ndxmapCreateIndex( "Size", "cities", @Compare2() )
      ndxmapCreateIndex( "Spaces", "cities", @Compare3() )
   Else
      ndxmapCreateIndex( "Alphabetic", "cities", @Compare1() )
      flag = 1
   EndIf
   
   f = ReadFile( #PB_Any, file )
   format = ReadStringFormat( f )
   
   t = ElapsedMilliseconds()
   
   While Not Eof(f)
      line = ReadString( f, format )
      AddMapElement( mapCities(), line, #PB_Map_NoElementCheck )
         mapCities()\city  = line
         mapCities()\size  = Len( line)
         mapCities()\spc   = CountString(Line, " ")
   Wend
   
   CloseFile( f )
   tmap = ElapsedMilliseconds() - t
   
   t = ElapsedMilliseconds()
   ForEach mapCities()
      ndxmapSetNDX( "Alphabetic" ) : ndxmapAdd( @mapCities() )
     
      If Not flag   
         ndxmapSetNDX( "Size" ) : ndxmapAdd( mapCities() )
         ndxmapSetNDX( "Spaces" ) : ndxmapAdd( mapCities() )
      EndIf
   Next
   
   recs1 = MapSize( mapCities() )
   tload = ElapsedMilliseconds() - t
   
   ;ListData( "Size" )
   
   ; We remove half the records
   i = 1
   t = ElapsedMilliseconds()
   
   ForEach mapCities()
      If Not (i % 2)
         ndxmapDelete( "cities", @mapCities() )
         DeleteMapElement( mapCities() )
      EndIf
      i + 1
   Next
   
   recs2 = MapSize( mapCities() )
   tdel = ElapsedMilliseconds() - t
   
   ;ListData( "Spaces" )
   
   ndxmapSetNDX( "Alphabetic" )
   msg =  "-- Loading Map --" + #LF$ +
          " " + StrD(tmap/1000,3) + " Seconds. [" + Str(recs1) + "] records loaded into map." + #LF$ +
          "-- Adding records --" + #LF$ +
          " " + StrD(tload/1000,3) + " Seconds. [" + Str(recs1) + "] records indexed." + #LF$ +
          "-- Deleting 50% records --" + #LF$ +
          " " + StrD(tdel/1000,3) + " Seconds. [" + Str(recs2) + "] records remain." + #LF$
   
   MessageRequester( "Duration", msg )
   
EndProcedure

 Procedure         MainWindow()
   
      If OpenWindow( #MainWindow, #PB_Ignore, #PB_Ignore, 700, 440, szTitle )
     
         ButtonGadget( #BtnExit, 20,   10, 110, 30, "EXIT" )
         ButtonGadget( #BtnLoad, 20,  55, 110, 30, "Load" )
         ButtonGadget( #BtnSearch, 20,  285, 110, 40, "Search" )
         ListViewGadget( #LVResults, 150, 0, 630, 440 )
         
         TextGadget(   #StrFind, 20, 170, 110, 20, "Look For" )
         StringGadget(  #EdFind, 20, 190, 110, 25, "" )
         CheckBoxGadget( #CBFastDel, 20, 370, 110, 25, "Use fast delete" )
         
         ProcedureReturn 1
      EndIf

      ProcedureReturn 0
   EndProcedure
     
; =====================================================================================
;- Entry point
; =====================================================================================
   
   Define         err, Event, e, ExitApplication
   Define.s       filename
   
   If MainWindow()
      filename = "cities2.txt"

      Repeat
         Event = WaitWindowEvent()
         
         Select Event
            Case #PB_Event_CloseWindow
               ExitApplication = #True
           
            Case #PB_Event_Gadget
                     
               e = EventGadget()
               
               If e = #BtnSearch
                 
               ElseIf e = #BtnExit
                  ExitApplication + 1
               
               ElseIf e = #BtnLoad
                  filename = OpenFileRequester( "Please choose file to load", "", "TXT Files|*.txt", 0 )
                 
                  If filename
                     SetWindowTitle( #MainWindow, szTitle + " -> " + filename )
                     
                     If GetGadgetState( #CBFastDel ) = #PB_Checkbox_Unchecked
                        LoadFile( filename, 0 )
                     Else
                        LoadFile( filename, 1 )
                     EndIf
                  EndIf
               EndIf
               
         EndSelect
       
      Until ExitApplication
   EndIf
   
; =====================================================================================
;- Compare Functions
; =====================================================================================

Procedure         Compare1( *p1.sts, *p2.sts )
   
   If *p1\city < *p2\city
      ProcedureReturn -1
   ElseIf *p1\city > *p2\city
      ProcedureReturn 1
   EndIf   
   
   ProcedureReturn 0
EndProcedure

Procedure         Compare2( *p1.sts, *p2.sts )
   
   Protected      val
   
   val = *p1\size - *p2\size
   
   If Not val
      ProcedureReturn Compare1( *p1.sts, *p2.sts )
   EndIf
   
   ProcedureReturn val
EndProcedure

Procedure         Compare3( *p1.sts, *p2.sts )
   Protected      val
   
   val = *p1\spc - *p2\spc
   
   If Not val
      ProcedureReturn Compare2( *p1.sts, *p2.sts )
   EndIf
   
   ProcedureReturn val
EndProcedure







_________________
I may not help with your coding
Just ask about mental issues!

http://www.lulu.com/spotlight/kingwolf
http://www.sen3.net


Top
 Profile  
Reply with quote  
 Post subject: Re: Index for Maps/Lists/Array [Updated]
PostPosted: Tue Jun 02, 2020 5:33 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4699
Location: Lyon - France
Can be usefull
Thanks for sharing 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye