Announcement

Collapse
No announcement yet.

Sort Array in TYPE..

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

  • Sort Array in TYPE..

    Wellknown issue. ARRAY SORT, -SCAN, cannot handle arrays in TYPE.

    I'm writing a syntax color text editor from scratch here and needed
    a way to sort an array within a TYPE, for implementation of bookmarks.
    Found a solution by declaring a similar, "ordinary" array at the same
    spot, but a bit unsure if it's safe to do this. Should be safe when
    working with fixed-length data, but still though I'd ask if anyone knows.

    Anyway, here's my take on the problem of using ARRAY SORT with arrays
    inside a TYPE declared variable (works fine, but is it safe?):
    Code:
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Solution to the problem of using ARRAY SORT, SCAN, etc,
    ' on an array inside a TYPE declared variable.
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    #COMPILE EXE
    #INCLUDE "Win32Api.Inc"
     
    TYPE Whatever
      item   AS LONG
      pos(4) AS LONG
    END TYPE
     
    FUNCTION PBMAIN()AS LONG
      LOCAL myArray AS Whatever, I AS LONG
     
      'Set values to TYPE array, 5 to 1
      FOR I = 0 TO 4 : myArray.pos(I) = 5 - I : NEXT
     
      MSGBOX STR$(myArray.pos(0)) & $CRLF & STR$(myArray.pos(1)) & $CRLF & _
             STR$(myArray.pos(2)) & $CRLF & STR$(myArray.pos(3)) & $CRLF & _
             STR$(myArray.pos(4)), %MB_ICONINFORMATION, "Unsorted array in TYPE"
     
      'Declare similar, ordinary array at TYPE array's location
      DIM tmp(4) AS LONG AT VARPTR(myArray.pos(0))
      ARRAY SORT tmp(0)       '<- sort temporary array
     
      'Array in TYPE is now sorted, 1 to 5..  :-)
      MSGBOX STR$(myArray.pos(0)) & $CRLF & STR$(myArray.pos(1)) & $CRLF & _
             STR$(myArray.pos(2)) & $CRLF & STR$(myArray.pos(3)) & $CRLF & _
             STR$(myArray.pos(4)), %MB_ICONEXCLAMATION, "Sorted array in TYPE!"
     
    END FUNCTION
    ------------------

  • #2
    It must be safe/effective, etc.

    That's why the ABSOLUTE array (DIM .. AT xxx) exists: so you can REDEFINE any block of memory for convenient access.

    In this case, the ARRAY redefines the TABLE embedded in the UDT.

    As another little trick with UDTs and VARPTR, you can get the offset of any member of a UDT without adding up all those members preceding it simply by asking for VARPTR (variable DIMed as TYPE) and subtracting from VARTPR (member in which you are interested).

    Can be handy for ARRAY SORT () FROM xxxx TO yyyy when the UDT contains lots of members.


    MCM




    [This message has been edited by Michael Mattias (edited January 06, 2001).]
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Hi,

      Fantastic tips guys, but in order to expand these ideas in my own
      code; and I would like to; I would need a tutorial on how PB stores
      arrays in memory.

      Would an array i.e B(3,3) would be stored
      in linear format like

      b(0,0);b(0,1);b(0,2);b(0,3);b(1,0);b(1,1).........b(3,3)

      or

      b(0,0);b(1,0);b(2,0)..............................b(3,3)

      Regards
      Trevor

      ------------------

      Comment


      • #4
        PowerBASIC uses column-major order for multi-dimensional arrays... see ARRAY SORT in the on-line help for more information. (The ARRAY sections discuss "strategies" for sorting multi-dimensional arrays safely - it is essential reading! )
        Code:
        [b]Linear column-major array order in memory:[/b]
        abc(0,0), …, abc(n,0), abc(0,1), …, abc(n,1), …, abc(0,x), …, abc(n,x)
        I hope this helps!

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

        Comment


        • #5
          Originally posted by Borje Hagsten:
          Code:
          TYPE Whatever
            item   AS LONG
            pos(4) AS LONG
          END TYPE
          
          <snipped for space>
          
            MSGBOX STR$(myArray.pos(0)) & $CRLF & STR$(myArray.pos(1)) & $CRLF & _
                   STR$(myArray.pos(2)) & $CRLF & STR$(myArray.pos(3)) & $CRLF & _
                   STR$(myArray.pos(4)), %MB_ICONINFORMATION, "Unsorted array in TYPE"
          Borje

          I know this is only a snippet, but it appears you have defined an
          array that is referenced by literals. First, if this is the case
          why not use constants to clarify the purpose of the elements --
          myArray.pos(%FIRSTPOS)? Secondly, the array does may it easier to
          initialize the array within a loop, but if the array is in fact to
          be referenced literally then it seems discrete elements would be a
          better choice since there are some gotchas with arrays in TYPEs.

          Code:
          TYPE Whatever
            item   AS LONG
            pos1   AS LONG
            pos2   AS LONG
            pos3   AS LONG
            pos4   AS LONG
          END TYPE
          Of course, if you are actually using variables to reference the
          array elements, then the point is moot. Either way, good use of
          mapping data structures. Very similar to mapped data in PB/DOS.

          ss


          ------------------

          Comment


          • #6
            Thank you for the input, fellows. Actually, for this purpose, I
            decided to take another route instead and use an array, where
            UBOUND = Linecount, to store %TRUE/%FALSE flags for every line.
            This enables setting many bookmarks, up to the number of lines
            and turned out to be much easier and a bit faster to handle. If
            one store line numbers, the array must be scanned for these each
            time the screen is redrawn. If each line has its own flag, no
            scanning is needed = much faster redrawing operations.

            It means some additional memory requirements, of course, but for
            this purpose, it's worth it. I like being able to set bookmarks
            in many places, so I can jump back and forth without limitation.

            I'll post the result as soon as it's ready. It may take a while,
            because there's a lot left to do with it and my time is limited,
            but I think you'll like the final result, since it will enable us
            to write our own PB editors (whatever) just the way we want them.
            I may even throw in some HTML syntax coloring capacity into it..

            To bad PB hasn't released the current editor as open source (was
            it Dave who wrote it?), but no big deal. Reinventing the wheel can
            sometimes make better wheels and PB has given us some excellent
            tools to do it with. The one I have in the makes here is already
            both faster, rounder and more feature rich, and I haven't even
            started optimizing the critical parts of it yet..


            ------------------

            Comment


            • #7
              For simple true/false arrays, why not use a bit array rather than a much larger numeric array?

              For example, for a bit array of 4096 "slots", you simply declare a LONG array of 4096/32= 128 values, and then use BIT(), BIT SET, etc, to query individual bits of the LONG array.

              See the BIT statement in the doc's for more information.


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

              Comment


              • #8
                An excellent tip, Lance, thanks. I may take you up on that.


                ------------------

                Comment

                Working...
                X