No announcement yet.

Tagarray twice

  • Filter
  • Time
  • Show
Clear All
new posts

  • Tagarray twice

    I need multiple tagarrays, it doesn't look that it can be done in pb?

    [email protected]

  • #2
    Edwin --

    The PowerBASIC languages don't currently support that. Here is a way to work around that limitation...

    Let's say you have an array of first names that you want to sort, and you want to TAGARRAY an array of last names and an array of phone numbers. (Obviously this is not a good way to write a program... I just wanted to use an example that would be clear.)

    Create a LONG array of the same size, and fill the array with values that match the element numbers. lTagArray(0) = 0, lTagArray(1) = 1, etc.

    Picture it like this:

    First Name  # Last Name  Phone
    ----------  - ---------- --------
    Edwin       1 Knoppert   555-1111
    Eric        2 Pearson    555-2222
    Edward      3 Smith      555-3333
    Erwin       4 Jones      555-4444
    Earl        5 Sandwich   555-5555
    If you sort the string array and use the numeric array as your TAGARRAY, you end up with this:

    First Name  # Last Name  Phone
    ----------  - ---------- --------
    Earl        5 Knoppert   555-1111
    Edward      3 Pearson    555-2222
    Edwin       1 Smith      555-3333
    Eric        2 Jones      555-4444
    Erwin       4 Sandwich   555-5555
    Since the Last Name and Phone arrays did not get sorted, they no longer align with the elements of the First Name array. But the LONG array did get sorted. So when you want the Last Name for Erwin (now element 5), you look at the LONG value that goes with Erwin, which is 4, and so look at element 4 of the Last Name array... Jones.

    In other words, instead of...

    PRINT sLastName(5) would do this everywhere...

    PRINT sLastName(lTagArray(5))
    This works well when you can't design your data to allow easier sorting. In the example above, of course, you could create a TYPE that contained a First Name, Last Name, and Phone field, and create an array of that TYPE. Then you could use ARRAY SORT without using a TAGARRAY at all. But it's not always possible/practical to do that.

    -- Eric

    Perfect Sync: Perfect Sync Development Tools
    Email: mailto:[email protected][email protected]</A>
    "Not my circus, not my monkeys."


    • #3
      By all means use a TYPE if at all possible. Failing that, try
      the following sort routine that I developed a number of years

      Last name is stored in a$(),
      First name is stored in b$() and
      Tele number is stored in c$()
      (I) points to the last record in the array

      for x = 2 to I ' Start with the second element
      k = x ' "Floating" pointer
      do until a$(k) => a$(k-1) or k = 1
      swap a$(k),a$(k-1)
      swap b$(k),b$(k-1)
      swap c$(k),c$(k-1)
      decr k
      next x

      This routine is short, sweet and to the point. It's slower than
      ARRAY SORT but it works reasonably fast with small to moderate
      size arrays.

      Hope this helps

      There are no atheists in a fox hole or the morning of a math test.
      If my flag offends you, I'll help you pack.


      • #4
        Very clever, Eric. I'll remember this one, thanks.



        • #5
          It's quite a lot of data copying though.

          A fast way is little bit like the earlier post to create another array or another field in a UDT and use it as an index.
          rather than copy the all the data fields back and forth as you sort you just modify the index. This is useful if you want to change the field that the index is based on or have multiple indexes. Once indexed you can then take advantage of binary searching etc to improve performance.
          Pointers can be used as indexes to increase performance too. You also then don't have to modify the original data.


          Paul Dwyer
          Network Engineer
          Aussie in Tokyo
          (Paul282 at VB-World)


          • #6
            To add a twist to Eric's suggestion, ARRAY SORT the new "index" array using the second _data_ array as a TAGARRAY, and it will be sorted in the same order as the initial array.

            Therefore, by using copies of the new "index" array, you can resort the multiple data arrays.

            Obviously this will use additional memory for an extra copy of the "index" array, but if you absolutely must do this, then it one solution what allows you to continue to use ARRAY SORT.

            Note that when dealing with dynamic string arrays, ARRAY SORT does it's work with the string handles rather than moving the string data, so by using an efficient sort algorithm (ie, quick sort; rather then the much slower bubble sort mentioned above), it is plausable to just swap string handles (4 bytes each).

            ie, instead of:
            SWAP strArr(lo), strArr(hi)
            you would use a LONG pointer that targets the string handle:
            DIM p1 AS LONG PTR, p2 AS LONG PTR
            p1 = VARPTR(strArr(lo)) ' string srray handle address
            p2 = VARPTR(strArr(hi))
            SWAP @p1,@p2

            Food for thought...

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


            • #7
              Thank you all!

              At the moment i combined the fields to one element but the tips are good for later use..

              [email protected]


              • #8
                Lance, sorting the index field and tagging the second data field will not produce the desired result. Using Eric's sample mentioned earlier, you would end up with:

                (2nd data)
                First Name # Last Name Phone
                ---------- - ---------- --------
                Earl 1 Smith 555-1111
                Edward 2 Jones 555-2222
                Edwin 3 Pearson 555-3333
                Eric 4 Sandwich 555-4444
                Erwin 5 Knoppert 555-5555

                Now the first names & second names no longer match up.

                To use ARRAY SORT w/TAGARRAY to correctly sort all the arrays (assuming you don't want to maintain an index array), you would need to create an array of the same type as the key array and copy the key array to the TEMP array, sort the TEMP array TAGGING a secondary array and recopying/sorting the TEMP array for every remaining data array until you only have the key array and one remaining data array where you can sort the key array and TAG the last data array.

                Bernard Ertl

                [This message has been edited by Bern Ertl (edited February 05, 2001).]
                Bernard Ertl
                InterPlan Systems