Page 1 of 1

multi dimensional array sort example please

Posted: Sat Mar 11, 2017 5:06 am
by bluebird
Would someone who has already don this coding, please supply an example.

I want to sort each sub array (9) into strings in ascending order resulting then into 9 ordered strings,
but I don't have the codeblock experience yet.

My array will be like this one:

PUBLIC aTest := {;
{ "5", "4", "1", "6", "7", "9", "8", "2", "3" }, ;
{ "0", "7", "6", "0", "0", "2", "0", "0", "0" }, ;
{ "4", "3", "9", "8", "1", "5", "7", "2", "6" }, ;
{ "4", "0", "0", "0", "5", "0", "0", "3", "0" }, ;
{ "0", "0", "0", "4", "2", "1", "0", "0", "0" }, ;
{ "0", "5", "0", "0", "8", "0", "0", "0", "7" }, ;
{ "6", "0", "0", "5", "9", "7", "0", "4", "0" }, ;
{ "0", "0", "0", "1", "0", "0", "9", "8", "0" }, ;
{ "9", "7", "1", "6", "2", "8", "5", "4", "3" } }

Then a new single dimensional array of 9 strings of sorted digits

Awaiting with anticipation

Thanks

Re: multi dimensional array sort example please

Posted: Sat Mar 11, 2017 9:53 am
by serge_girard
Hello Bluebird,

Try this (maybe it can be done shorter, but it works)

Code: Select all

#include "hmg.ch"


FUNCTION MAIN()

PUBLIC aTest := {;
{ "5", "4", "1", "6", "7", "9", "8", "2", "3" }, ;
{ "0", "7", "6", "0", "0", "2", "0", "0", "0" }, ;
{ "4", "3", "9", "8", "1", "5", "7", "2", "6" }, ;
{ "4", "0", "0", "0", "5", "0", "0", "3", "0" }, ;
{ "0", "0", "0", "4", "2", "1", "0", "0", "0" }, ;
{ "0", "5", "0", "0", "8", "0", "0", "0", "7" }, ;
{ "6", "0", "0", "5", "9", "7", "0", "4", "0" }, ;
{ "0", "0", "0", "1", "0", "0", "9", "8", "0" }, ;
{ "9", "7", "1", "6", "2", "8", "5", "4", "3" } }

SET PRINTER TO sort.TXT 
SET PRINTER ON 
SET CONSOLE OFF

? 'UNSORTED'
?
FOR a = 1 TO LEN(aTEST)
   FOR b = 1 TO LEN(aTEST)
      ?? aTEST [a] [b] + ' '
   NEXT 
   ?
NEXT



aTest3 := {}  // new sorted array
FOR a = 1 TO LEN(aTEST)
    
   // put array into string
   x := ''
   FOR b = 1 TO LEN(aTest) - 1
      x := x +  aTest [a] [b]  + ','
   NEXT 
   x := x +  aTest [a] [b]   
   
   // create arrya, sort it and add to result array   
   aList := HB_ATOKENS( x, ',' )
   ASORT(aList)
   AADD(aTest3, aList)
  
NEXT

? 'SORTED'
?
FOR a = 1 TO LEN(aTEST3)
   FOR b = 1 TO LEN(aTEST3)
      ?? aTEST3 [a] [b] + ' '
   NEXT 
   ?
NEXT

SET PRINTER TO  
SET PRINTER Off
SET CONSOLE On
 
 
Serge

Re: multi dimensional array sort example please

Posted: Sat Mar 11, 2017 12:02 pm
by PeteWG
Hi,

Not sure I did understand what exactly sorting you want,
maybe the below code is what you're looking for:

Code: Select all

PROCEDURE Main()
   MEMVAR aTest
   LOCAL aStrings := {}
   LOCAL aSub, s

   PUBLIC aTest := {;
   { "5", "4", "1", "6", "7", "9", "8", "2", "3" }, ;
   { "0", "7", "6", "0", "0", "2", "0", "0", "0" }, ;
   { "4", "3", "9", "8", "1", "5", "7", "2", "6" }, ;
   { "4", "0", "0", "0", "5", "0", "0", "3", "0" }, ;
   { "0", "0", "0", "4", "2", "1", "0", "0", "0" }, ;
   { "0", "5", "0", "0", "8", "0", "0", "0", "7" }, ;
   { "6", "0", "0", "5", "9", "7", "0", "4", "0" }, ;
   { "0", "0", "0", "1", "0", "0", "9", "8", "0" }, ;
   { "9", "7", "1", "6", "2", "8", "5", "4", "3" } }

   FOR EACH aSub IN aTest
      s := ""
      AEval( ASort( aSub ), {|e| s += e} )
      AAdd( aStrings, s )
   NEXT
   // aStrings := ASort( aStrings ) // uncomment this line if you also need aStrings sorted

   hb_Alert( aStrings )
   
   RETURN
regards,

---
Pete

Re: multi dimensional array sort example please

Posted: Sat Mar 11, 2017 6:18 pm
by bluebird
Thank you to Serge and PeteWG

The examples will work, I will study them carefully

Now I want to add this question, viz.

I also want to sort the same array columns and compare the result to the "alldigits" string as a test that the column data is also full and no digits are missing.
In my own muddling way I found that this line works on sorting rows i.e.

AEVAL(aTest, { | nVal, nIdx | ASort(aTest[nIdx]) }, 1, 9 )

how can I make it work on columns 1 to 9?

Thanks, great support

Re: multi dimensional array sort example please

Posted: Sun Mar 12, 2017 7:54 am
by serge_girard
Bluebird,

Maybe the AEVAL in a FOR/NEXT loop?

Serge

Re: multi dimensional array sort example please

Posted: Mon Mar 13, 2017 9:53 pm
by bluebird
Dear mentors and readers

I have had a hang up about dealing with multi dimensional arrays. Seeing how to operate row by row is OK but how do you operate (example sort) by columns when multidimensional arrays are just nested rows in Clipper .

An easy solution???
My idea now is to treat the array as a matrix. It you transpose a matrix each row becomes a column in the transposed matrix (or AKA array).Now you can process the columns in the old array because they are now rows in the transpose.

aMatix:=array(5,3) transposes to bMatrix:=array(3,5). Shouldn't matter what the element types are (numbers, strings,etc)

I am wondering if there is a way to implement an "array" transpose into a codeblock.

Thanks for putting up with my unique problems.

Re: multi dimensional array sort example please

Posted: Tue Mar 14, 2017 8:06 am
by trmpluym
Bluebird,

Did you read this article ?

https://vivaclipper.wordpress.com/2013/ ... ay-basics/

This sample is a good example to sort an array with 2 dimensions:
This example sorts a nested array using the second element of each sub-array:

aKids := { {"Mary", 14}, {"Joe", 23}, {"Art", 16} }
aSortKids := ASORT(aKids,,, { |x, y| x[2] < y[2] })
Result:

{ {“Mary”, 14}, {“Art”, 16}, {“Joe”, 23} }
Theo