Announcement

Collapse
No announcement yet.

SORT a TYPE ?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • SORT a TYPE ?

    Can you sort an array of a TYPE?
    for example ...

    Code:
    TYPE HDfileStruct
        fName       AS STRING*10 
        fSize       AS LONG      
        First       AS LONG      
        Last        AS LONG
        SymStr      AS STRING*12 
        CtrStr      AS STRING*12 
    END TYPE   
    
    GLOBAL HDfile() AS HDfileStruct 
    
    '
    '
    ' fill up the array elements...
    '
    '
        ARRAY SORT HDfile(), COLLATE UCASE ' sort on fName ?
    will that work? does it sort on the first item in the TYPE?


    And how about:

    REDIM PRESERVE HDfile(2)

    will that work also?
    ------------------
    Kind Regards
    Mike


    [This message has been edited by Mike Trader (edited August 24, 2001).]

  • #2
    ARRAY SORT treats UDT arrays like fixed-length string arrays (whose subscript width is the size of the UDT), so it sorts based on the entire content of the UDT.

    If the UDT includes numeric variables, then you would be best to use the FROM..TO clause to restrict the byte positions that SORT uses for the sorting.

    Yes, you can use REDIM and REDIM PRESERVE on UDT arrays.

    However, you cannot use REDIM on an array within a UDT, nor can you directly sort an array within a UDT.

    But there is a solution for sort such arrays: use DIM..AT to dimension an array at the same memory location as the array within the UDT, then use ARRAY SORT on that array.

    I hope this helps!

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>
    Lance
    mailto:[email protected]

    Comment


    • #3
      WOW! this language is amazing.

      thx Lance

      ------------------
      Kind Regards
      Mike

      Comment


      • #4
        ARRAY SORT treats UDT arrays like fixed-length string arrays (whose subscript width is the size of the UDT), so it sorts based on the entire content of the UDT.
        Unless you use the FROM x TO Y option, in which case it sorts only on the specified characters.

        Don't feel like counting bytes when you want to sort on a specific member of a UDT? Tired of finding all those sort keys when you add/change delete a member of a UDT?

        So let the compiler do the work:
        Code:
          TYPE MapIndexType
             MapKey    AS MapKeyType
             SubNo     AS LONG           
          END TYPE
          LOCAL SortStart AS LONG, SortEnd AS LONG
        
             REDIM MapIndex     (nMapItems) AS MapIndexType
             { fill the array with data }
        ' calculate the sort specs...
             SortStart = VARPTR (MapIndex(0).MapKey) - VARPTR (MapIndex(0)) + 1
             SortEnd   = SortStart + SIZEOF(MapIndex(0).MapKey) -1
             ARRAY SORT MapIndex(), FROM SortStart TO SortEnd
        MCM


        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          What a great tip, Michael! Thanks!


          ------------------
          Lance
          PowerBASIC Support
          mailto:[email protected][email protected]</A>
          Lance
          mailto:[email protected]

          Comment


          • #6
            Well continuing with this logic i should be able to do an ARRAY
            scan. The following finds a match on element 3 not 2.

            I dont understand why.

            Code:
            #COMPILE EXE "Test.exe"
             
            TYPE HDfileStruct
                fName       AS STRING*10 
                S           AS LONG     
                d           AS STRING*10 
                t           AS STRING*10
            END TYPE 
            GLOBAL HDfile() AS HDfileStruct
             
            '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
            FUNCTION PBMAIN
            LOCAL i AS LONG, Res AS LONG
             
            DIM HDFile(4)
             
            HDfile(1).fName="123456789"
            HDfile(2).fName="23456789"
            HDfile(3).fName="3456789"
            HDfile(4).fName="456789"
             
                ARRAY SCAN HDfile(), FROM 1 TO 4, = "2345", TO Res '= FileSrch(1, i), TO Res
                MSGBOX HDfile(Res).fName,,STR$(Res)
             
            END FUNCTION

            ------------------
            Kind Regards
            Mike

            Comment


            • #7
              The return result from ARRAY SCAN is a relative index value.

              That is, your array starts at HDFile(0) (which is not "filled" in your code but is defined in the DIM statement), so when a match in HDFile(2) is made, it is indicated as a relative match as the third subscript in the array, hence ARRAY SCAN returns 3.

              I hope that clears this up!


              ------------------
              Lance
              PowerBASIC Support
              mailto:[email protected][email protected]</A>
              Lance
              mailto:[email protected]

              Comment


              • #8
                I believe that this works.

                Code:
                #COMPILE EXE "Test.exe"
                
                TYPE HDfileStruct
                fName AS STRING*10
                S AS LONG
                d AS STRING*10
                t AS STRING*10
                END TYPE
                GLOBAL HDfile() AS HDfileStruct
                
                '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                FUNCTION PBMAIN
                LOCAL i AS LONG, Res AS LONG
                
                DIM HDFile(1 TO 4)
                
                HDfile(1).fName="123456789"
                HDfile(2).fName="23456789"
                HDfile(3).fName="3456789"
                HDfile(4).fName="456789"
                
                ARRAY SCAN HDfile(), FROM 1 TO 4, = "2345", TO Res '= FileSrch(1, i), TO Res
                MSGBOX HDfile(Res).fName,,STR$(Res)
                
                END FUNCTION
                ------------------

                Comment


                • #9
                  relative. got it.

                  OK now a little while back soneone said I could read and write
                  a TYPE directly. I tried with:

                  Code:
                  OPEN "text.txt" FOR OUTPUT AS 200 
                  FOR i = 1 TO 4
                      HDfile(1).fName=DATE$
                      HDfile(1).n=i*562
                      HDfile(1).d=DATE$
                      HDfile(1).t=TIME$
                      PRINT #200, HDfile(1) ' no good
                     'WRITE #200, HDfile(1) ' no good
                  NEXT
                  CLOSE #200
                  but the long is garbage.
                  Same thing with:

                  INPUT #200, HDfile()



                  ------------------
                  Kind Regards
                  Mike

                  Comment


                  • #10
                    I don't know if it helps, but I read a text file
                    into a UDT like so. Then I work with the components
                    of the UDT. Works well for me.

                    Code:
                    SUB GetData(fdata$) 'load data from text file into UDT
                     LOCAL d$,o#,h#,l#,cl#
                       OPEN fdata$ FOR INPUT AS #1 LEN = 16384
                     c&=0
                      DO
                        INCR c&
                        INPUT# 1, d$, o#, h#, l#, cl#
                          datarec(c&).d = d$
                          datarec(c&).o = o#
                          datarec(c&).h = h#
                          datarec(c&).l = l#
                          datarec(c&).cl = cl#
                          datarec(c&).c = c&
                      LOOP UNTIL EOF(1)
                      CLOSE
                      REDIM PRESERVE datarec(1 TO c&)
                    ------------------

                    Comment


                    • #11
                      To write/read UDT's with files, you should open the files in
                      RANDOM mode and use the UDT's as records.

                      EX:

                      Code:
                      TYPE ANYTHING
                          label1 AS ASCIIZ*%MAX_PATH
                          label2 AS LONG
                          label3 AS ASCIIZ*500
                      END TYPE
                      
                      DIM Z(1 to 10) AS ANYTHING
                      'Then:
                      
                      DIM FF AS LONG
                      FF = FREEFILE
                      OPEN "c:\temporary file.sat" FOR RANDOM AS #FF LEN = SIZEOF(ANYTHING)
                      
                      FOR L& = 1 TO 10
                          PUT #FF, L&, Z(L&)
                      NEXT
                      
                      DIM X(1 to 10) AS ANYTHING
                      
                      FOR L& = 1 TO 10
                          GET #FF, L&, X(L&)
                      NEXT
                      Regards,


                      ------------------
                      Clay C. Clear

                      mailto:[email protected][email protected]</A>

                      Clay Clear's Software

                      Comment


                      • #12
                        BINARY mode will work too...

                        Basically, numeric-class variables (and UDT members) are stored in binary format, not ASCII format, so viewing any data written to disk in this manner will appear as "garbage". That is, if you are storing such data, don't expect to be able to use an ASCII editor or file viewer to display the disk file.




                        ------------------
                        Lance
                        PowerBASIC Support
                        mailto:[email protected][email protected]</A>
                        Lance
                        mailto:[email protected]

                        Comment


                        • #13
                          aaaaaaaaaaaaaaaaah .... thats piece of information I was missing.

                          Thx guys

                          ------------------
                          Kind Regards
                          Mike

                          Comment


                          • #14
                            i posted a quicksort function a while back which is designed to sort a udt array on one member. it may or may not be useful to you.

                            regards,
                            ron


                            [this message has been edited by ron pierce (edited august 26, 2001).]

                            Comment


                            • #15
                              i posted a quicksort function a while back which is designed to sort a udt array on one member. it may or may not be useful to you.
                              as noted in that thread, unless numerics are reformatted, you do not get a true numeric sort.

                              but.. at



                              .. are some functions which convert any numeric into string signed binary (ssb) format, in which the values, when sorted as string characters,sort in true numeric order.

                              i invented ssb format during the ms-dos epoch, when memory was just not available. under win/32, it's a lot easier to just create a key array of numeric data, and sort that with the udt array as a "tagarray"

                              ssb can still be useful, though, if you need to build a composite key in which one or more of the key elements are numeric and you don't feel like doing a multi-key-sort the "long" way.

                              mcm
                              Michael Mattias
                              Tal Systems (retired)
                              Port Washington WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                              • #16
                                Similar to Michael's SSB example, I use these two functions to convert a LONG integer
                                to & from a 4-byte string that will sort properly if it's part of a record or UDT...
                                Code:
                                FUNCTION LongToKey(KeyVal AS LONG) AS STRING
                                   ' Converts a long integer value to a 4-byte string that can be used in
                                   ' a record where it needs to sort properly as part of a key segment.
                                   '
                                   X& = 2 ^ 31
                                   FUNCTION = STRREVERSE$(MKL$(KeyVal + X&))
                                END FUNCTION
                                 
                                FUNCTION KeyToLong(KeyVal AS STRING) AS LONG
                                   ' Converts a 4-byte string that was created by the
                                   ' LongToKey function back to it's original numeric value.
                                   '
                                   X& = 2 ^ 31
                                   FUNCTION = CVL(STRREVERSE$(KeyVal)) - X&
                                END FUNCTION
                                Timm
                                mailto:[email protected]
                                Tsunami Record Manager

                                Comment


                                • #17
                                  As noted in that thread, unless numerics are reformatted, you do not get a true numeric sort.
                                  The QuickSort does sort numerics correctly (by value).

                                  Comment

                                  Working...
                                  X