multi dimensional array sort example please

Topic Specific Tutorials and Tips.

Moderator: Rathinagiri

Post Reply
bluebird
Posts: 172
Joined: Wed Sep 28, 2016 3:55 am
DBs Used: DBF

multi dimensional array sort example please

Post 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
User avatar
serge_girard
Posts: 3165
Joined: Sun Nov 25, 2012 2:44 pm
DBs Used: 1 MySQL - MariaDB
2 DBF
Location: Belgium
Contact:

Re: multi dimensional array sort example please

Post 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
There's nothing you can do that can't be done...
PeteWG
Posts: 176
Joined: Sun Mar 21, 2010 5:45 pm

Re: multi dimensional array sort example please

Post 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
bluebird
Posts: 172
Joined: Wed Sep 28, 2016 3:55 am
DBs Used: DBF

Re: multi dimensional array sort example please

Post 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
User avatar
serge_girard
Posts: 3165
Joined: Sun Nov 25, 2012 2:44 pm
DBs Used: 1 MySQL - MariaDB
2 DBF
Location: Belgium
Contact:

Re: multi dimensional array sort example please

Post by serge_girard »

Bluebird,

Maybe the AEVAL in a FOR/NEXT loop?

Serge
There's nothing you can do that can't be done...
bluebird
Posts: 172
Joined: Wed Sep 28, 2016 3:55 am
DBs Used: DBF

Re: multi dimensional array sort example please

Post 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.
trmpluym
Posts: 303
Joined: Tue Jul 15, 2014 6:52 pm
Location: The Netherlands

Re: multi dimensional array sort example please

Post 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
Post Reply