Announcement

Collapse
No announcement yet.

Array Sort with a multi-dimensional string array

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

  • Array Sort with a multi-dimensional string array

    Friends,
    I have a matrix of information stored in a two dimensional string array(1:9000,1:12) that is essentially 9000 records of 12 elements.
    How do I use ARRAY SORT to sort the string array by the first element while keeping the 11 trailing elements associated with the first element? This would be similar to a TAGALONG array, but within the same matrix.
    Thanks. Any help will be appreciated.
    -Tom Houlihan

  • #2
    Code:
    'Given: Array ( 1:9000, 1:12) 
    
    REDIM KEY(1:9000) AS STRING, Subscript(1:9000) AS LONG
    
    FOR Z = 1 TO 9000
      Key(Z) = Array (Z,1) '(subscript 1 of dimension 2 is the key?) 
      Subscript (Z) = Z
    NEXT  
    
    ARRAY SORT KEY(), TAGARRAY Subscript()
    
    FOR Z = 1 TO 9000
    
      FOR ZZ = 1 TO 12 
          MyItem  =  Array (Subscript(z), ZZ) 
      NEXT
    NEXT
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Array Sort with a multi-dimensional array

      Michael,
      Thanks for your suggestion.
      The way I read it, I'll build an array of the key values along with an array of the index numbers, sort the array of keys values and tagging along the array of index numbers, then read the multi dimensional array in a sequence based on the sorted index numbers.
      Is that right?
      -Tom

      Comment


      • #4
        That's why indexes are used.

        Full disclosure: I have never been able to understand direct sorting of multi-dimension arrays with ARRAY SORT. Frankly, when I have this situation I think of the second dimension as "columns of a record" so I don't even use a second dimension... I just store the columns in a UDT or delimit them in single-dimension "array of records."

        I think there's a another current thread on this very subject here, with multiple options posted by multiple users.

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

        Comment


        • #5
          Thx for the snippet.

          Code:
          'I'm trying to sort, in descending order, the ratio of VAL(a$(2,r))/VAL(a$(3,r))
          'but am failing so...I wrote this example but...can't see what's wrong i.e....
          'It looks to start off ok...big numbers first...but then seems to lose the plot...
          'Any ideas??
          
          #COMPILE EXE
          #DIM ALL
          #DEBUG ERROR ON
          #DEBUG DISPLAY ON
          
          MACRO SEP =& "," &
          
          SUB Show_array( a$())
              LOCAL r, c, max_rows, max_cols AS LONG
              LOCAL txt$
              max_cols = UBOUND(a$,1)
              max_rows = UBOUND(a$,2)
              FOR r = 1 TO max_rows
                  txt$ = txt$ & USING$( "\      \", a$(1,r) ) SEP _
                                USING$( "\      \", a$(2,r) ) SEP _
                                USING$( "\      \", a$(3,r) ) SEP _
                                USING$( "\      \", a$(4,r) ) & $CRLF
              NEXT i
              ? txt$
          END SUB
          
          SUB Sort_array( BYREF a$(), BYREF sorted_a$() )
              LOCAL r, c, max_rows, max_cols, key(), subscript() AS LONG
              max_cols = UBOUND(a$,1)
              max_rows = UBOUND(a$,2)
              DIM key(1 TO max_rows), subscript(1 TO max_rows)
              FOR r = 1 TO max_rows
                  key(r) = VAL( a$(max_cols,r) )
                  subscript(r) = r
              NEXT
              ARRAY SORT key(), TAGARRAY subscript(), DESCEND
              FOR r = 1 TO max_rows
                  FOR c = 1 TO max_cols
                      sorted_a$(c,r) = a$(c,Subscript(r))
                  NEXT
              NEXT
          END SUB
          
          FUNCTION PBMAIN () AS LONG
              LOCAL a$(),sorted_a$(),txt$
              LOCAL r,c,max_rows,max_cols AS LONG
              max_rows=10 : max_cols=4
              DIM a$(1 TO max_cols, 1 TO max_rows), sorted_a$(1 TO max_cols, 1 TO max_rows)
              FOR r = 1 TO max_rows
                  FOR c = 1 TO max_cols
                      IF c=1 THEN a$(1,r)="r" & TRIM$(STR$(r)) & "c" & TRIM$(STR$(c))
                      IF c=2 THEN a$(2,r)=TRIM$( STR$( RND(100,2000) ) )
                      IF c=3 THEN a$(3,r)=TRIM$( STR$( RND(100,2000) ) )
                      IF c=4 THEN a$(4,r)=TRIM$( STR$( VAL(a$(2,r))/VAL(a$(3,r)) ) )
                  NEXT c
              NEXT r
              Show_array( a$() )
              Sort_array( a$(), sorted_a$() )
              Show_array( sorted_a$() )
          END FUNCTION
          Last edited by Dean Gwilliam; 16 Feb 2011, 03:30 PM.

          Comment


          • #6
            a different approach

            Code:
                local oQ as S3QueryClass0
                '
                oQ = class "S3QueryViewClass"   
                oQ.Opendb() ' open memory database
                oQ.SQL = "create table the9000(col1, col2, col3, col4, col5,col6,col7,col8,col9,col10, col11, col12)
                oQ.Query
                call loadmydata ' load the data into the table
                oQ.SQL = "select * from the9000 order by column1"
                oQ.Query
                ' now you have an index array of 9000 x 12 asciz pointers in the desired order
                '
            Last edited by Chris Holbrook; 16 Feb 2011, 05:12 PM.

            Comment


            • #7
              Just a few lines modified to assure the ratio is the key sort:
              Code:
              #COMPILE EXE
              #DIM ALL
              #DEBUG ERROR ON
              #DEBUG DISPLAY ON
              GLOBAL tmpArr() AS STRING
              
              MACRO SEP =& "," &
              
              SUB Show_array( a$())
                  LOCAL r, c, max_rows, max_cols AS LONG
                  LOCAL txt$
                  max_cols = UBOUND(a$,1)
                  max_rows = UBOUND(a$,2)
                  DIM tmpArr(1 TO max_rows) AS STRING
                  FOR r = 1 TO max_rows
                      tmpArr(r) =   USING$( "\      \", a$(1,r) ) SEP _
                                    USING$( "\      \", a$(2,r) ) SEP _
                                    USING$( "\      \", a$(3,r) ) SEP _
                                    USING$( "\      \", a$(4,r) ) & $CRLF
                  NEXT i
                  txt = JOIN$(tmpArr(), "")
                  ? txt$
              END SUB
              
              SUB Sort_array( BYREF a$(), BYREF sorted_a$() )
                  LOCAL r, c, max_rows, max_cols, subscript() AS LONG
                  max_cols = UBOUND(a$,1)
                  max_rows = UBOUND(a$,2)
                  DIM key(1 TO max_rows) AS DOUBLE
                  FOR r = 1 TO max_rows
                     key(r) = VAL(MID$(tmpArr(r), INSTR(-1, tmpArr(r), ",") + 1)) 'this key sorts on the value of the ratio
                  NEXT
                  ARRAY SORT key(), TAGARRAY tmpArr(), DESCEND
              END SUB
              
              FUNCTION PBMAIN () AS LONG
                  LOCAL a$(),sorted_a$(),txt$
                  LOCAL lineo AS STRING
                  LOCAL r,c,max_rows,max_cols AS LONG
                  max_rows=10 : max_cols=4
                  DIM a$(1 TO max_cols, 1 TO max_rows), sorted_a$(1 TO max_cols, 1 TO max_rows)
                  FOR r = 1 TO max_rows
                      FOR c = 1 TO max_cols
                          IF c=1 THEN a$(1,r)="r" & TRIM$(STR$(r)) & "c" & TRIM$(STR$(c))
                          IF c=2 THEN a$(2,r)=TRIM$( STR$( RND(100,2000) ) )
                          IF c=3 THEN a$(3,r)=TRIM$( STR$( RND(100,2000) ) )
                          IF c=4 THEN a$(4,r)=TRIM$( STR$( VAL(a$(2,r))/VAL(a$(3,r)) ) )
                      NEXT c
                  NEXT r
                  lineo = JOIN$(a(), "|")
                  Show_array( a$() )
                  Sort_array( a$(), sorted_a$() )
                  Show_array( tmpArr() )
              END FUNCTION
              
              [LEFT][/LEFT]

              Comment


              • #8
                Code:
                REDIM KEY(1:9000) AS STRING, Subscript(1:9000) AS LONG
                This changes in PB 10, as I understand, you'll need to use the " TO " instead of the ":"

                Code:
                REDIM KEY(1 TO 9000) AS STRING, Subscript(1 TO 9000) AS LONG
                3.14159265358979323846264338327950
                "Ok, yes... I like pie... um, I meant, pi."

                Comment


                • #9
                  Hi Dean,

                  I think the problem is just that you declared KEY() as LONG. Being a ratio, it rather should be SINGLE or DOUBLE as John Gleason did. OTOH, in PBCC5.X KEY is a KEYWORD. Also, $CRLF is not printable in the screen, just good in a file

                  Regards,

                  Code:
                   
                  #COMPILE EXE
                  #DIM ALL
                  #DEBUG ERROR ON
                  #DEBUG DISPLAY ON
                  MACRO SEP =& "," &
                  SUB Show_array( a$())
                      LOCAL r, c, max_rows, max_cols AS LONG
                      LOCAL txt$
                      max_cols = UBOUND(a$,1)
                      max_rows = UBOUND(a$,2)
                      FOR r = 1 TO max_rows
                          txt$ = txt$ & USING$( "\      \", a$(1,r) ) SEP _
                                        USING$( "\      \", a$(2,r) ) SEP _
                                        USING$( "\      \", a$(3,r) ) SEP _
                                        USING$( "\      \", a$(4,r) )
                       ?txt$
                       txt$=""
                      NEXT r
                  END SUB
                  SUB Sort_array( BYREF a$(), BYREF sorted_a$() )
                      LOCAL r, c, max_rows, max_cols, subscript() AS LONG
                      LOCAL keye() AS DOUBLE
                      max_cols = UBOUND(a$,1)
                      max_rows = UBOUND(a$,2)
                      DIM keye(1 TO max_rows), subscript(1 TO max_rows)
                      FOR r = 1 TO max_rows
                          keye(r) = VAL( a$(4,r) )
                          subscript(r) = r
                      NEXT
                      ARRAY SORT keye(), TAGARRAY subscript(), DESCEND
                      FOR r = 1 TO max_rows
                          FOR c = 1 TO max_cols
                              sorted_a$(c,r) = a$(c,Subscript(r))
                          NEXT
                      NEXT
                  END SUB
                  FUNCTION PBMAIN () AS LONG
                      LOCAL a$(),sorted_a$(),txt$
                      LOCAL r,c,max_rows,max_cols AS LONG
                      max_rows=10 : max_cols=4
                      DIM a$(1 TO max_cols, 1 TO max_rows), sorted_a$(1 TO max_cols, 1 TO max_rows)
                      FOR r = 1 TO max_rows
                          FOR c = 1 TO max_cols
                              IF c=1 THEN a$(1,r)="r" & TRIM$(STR$(r)) & "c" & TRIM$(STR$(c))
                              IF c=2 THEN a$(2,r)=TRIM$( STR$( RND(100,2000) ) )
                              IF c=3 THEN a$(3,r)=TRIM$( STR$( RND(100,2000) ) )
                              IF c=4 THEN a$(4,r)=TRIM$( STR$( VAL(a$(2,r))/VAL(a$(3,r)) ) )
                          NEXT c
                      NEXT r
                      Show_array( a$() )
                      Sort_array( a$(), sorted_a$() )
                      Show_array( sorted_a$() )
                      WAITKEY$
                  END FUNCTION

                  Comment


                  • #10
                    Chris...
                    Thanks for the alternative. It looks very elegant and my main app is SQLite/SQLitening-based so it is very pertinent to what I'm doing.

                    John, Jim, Manuel...
                    I had a feeling I was doing something stupid so...thanks for pointing it out!
                    I wasted hours searching for the problem yesterday and...
                    'cos I was seeing fractions, missed that key should be a SINGLE/DOUBLE.
                    Thanks very much indeed for pointing it out.

                    Comment

                    Working...
                    X