Page 1 of 1

Sorting arrays and storing them as variables.

Posted: Thu Sep 14, 2023 12:51 pm
by edk
Friends, I have two questions/problems regarding arrays and sorting them.
I have a multidimensional array where the first element is a number and the second element is a date. My task is to sort the array by date and within the same date to sort by number.
Below is the code I use.

Code: Select all

#include "hmg.ch"

Function main()

Local aArray := {{772865, 0d20230407}, {773341, 0d20230102}, {773342, 0d20230411}, {773343, 0d20230411}, {773352, 0d20230411}, ;
           {770642, 0d20230329}, {770647, 0d20230329}, {773602, 0d20230412}, {777113, 0d20230426}, {779616, 0d20230510}, ;
           {775479, 0d20230419}, {775481, 0d20230419}, {774897, 0d20230417}, {775777, 0d20230420}, {775779, 0d20230420}, ;
           {770366, 0d20230328}, {772731, 0d20230406}, {773644, 0d20230412}, {773645, 0d20230412}, {777141, 0d20230426}, ;
           {774852, 0d20230417}, {774854, 0d20230417}, {770034, 0d20230327}, {776554, 0d20230424}, {776561, 0d20230424}, ;
           {774147, 0d20230414}, {775800, 0d20230420}, {775802, 0d20230420}, {775803, 0d20230420}, {775805, 0d20230420}, ;
           {775806, 0d20230420}, {779672, 0d20230510}, {775804, 0d20230420}, {775807, 0d20230420}, {775239, 0d20230418}, ;
           {775240, 0d20230418}, {774208, 0d20230414}, {774210, 0d20230414}, {771936, 0d20230403}, {774851, 0d20230417}, ;
           {774856, 0d20230417}, {771260, 0d20230331}, {773973, 0d20230413}, {773971, 0d20230413}, {773317, 0d20230411}, ;
           {778976, 0d20230508}, {772861, 0d20230407}, {773340, 0d20230411}, {773351, 0d20230411}, {773392, 0d20230411}, ;
           {773394, 0d20230411}, {774169, 0d20230414}, {777599, 0d20230428}, {777602, 0d20230428}, {779383, 0d20230509}, ;
           {770942, 0d20230330}, {770944, 0d20230330}, {772014, 0d20230403}, {773737, 0d20230412}, {773739, 0d20230412}, ;
           {776617, 0d20230424}, {776619, 0d20230424}, {773972, 0d20230413}, {777463, 0d20230427}, {770086, 0d20230327}, ;
           {776557, 0d20230424}, {776558, 0d20230424}, {776556, 0d20230424}, {776562, 0d20230424}, {778925, 0d20230508}, ;
           {770367, 0d20230328}, {773390, 0d20230411}, {773391, 0d20230411}, {778110, 0d20230504}, {771058, 0d20230330}, ;
           {771062, 0d20230330}, {773974, 0d20230413}, {773975, 0d20230413}, {777462, 0d20230427}, {777464, 0d20230427}, ;
           {770036, 0d20230327}, {770038, 0d20230327}, {776550, 0d20230424}, {774850, 0d20230417}, {774848, 0d20230417}, ;
           {774849, 0d20230417}, {776553, 0d20230424}, {776559, 0d20230424}, {774228, 0d20230414}, {774229, 0d20230414}, ;
           {774233, 0d20230414}, {774234, 0d20230414}, {777598, 0d20230428}, {777601, 0d20230428}, {775685, 0d20230420}, ;
           {773600, 0d20230412}, {771970, 0d20230403}, {772864, 0d20230407}, {776551, 0d20230424}, {776552, 0d20230424}, ;
           {777596, 0d20230428}, {777597, 0d20230428}, {773668, 0d20230412}, {779681, 0d20230510}, {773318, 0d20230411}, ;
           {775431, 0d20230419}, {775518, 0d20230419}, {770013, 0d20230327}, {776548, 0d20230424}, {775686, 0d20230420}, ;
           {775684, 0d20230420}, {776564, 0d20230424}, {770643, 0d20230329}, {770646, 0d20230329}, {773597, 0d20230412}, ;
           {773599, 0d20230412}, {773601, 0d20230412}, {777137, 0d20230426}, {777143, 0d20230426}, {779038, 0d20230508}, ;
           {770708, 0d20230329}, {770709, 0d20230329}, {775183, 0d20230418}, {774153, 0d20230414}, {774157, 0d20230414}, ;
           {771971, 0d20230403}, {774873, 0d20230417}, {777140, 0d20230426}, {777142, 0d20230426}, {779600, 0d20230510}, ;
           {770015, 0d20230327}, {776560, 0d20230424}, {774151, 0d20230414}, {774156, 0d20230414}, {777600, 0d20230428}, ;
           {775473, 0d20230419}, {775476, 0d20230419}, {775477, 0d20230419}, {775478, 0d20230419}, {775482, 0d20230419}, ;
           {773629, 0d20230412}, {773631, 0d20230412}, {775241, 0d20230418}, {775242, 0d20230418}, {775243, 0d20230418}, ;
           {779574, 0d20230510}, {772687, 0d20230406}, {775432, 0d20230419}, {771211, 0d20230331}, {771214, 0d20230331}, ;
           {773344, 0d20230411}, {777238, 0d20230426}, {776555, 0d20230424}, {773690, 0d20230412}, {770018, 0d20230102}, ;
           {770016, 0d20230327}, {772533, 0d20230405}, {773643, 0d20230412}, {775434, 0d20230419}, {775435, 0d20230419}, ;
           {776808, 0d20230425}, {776809, 0d20230425}, {777563, 0d20230428}, {773319, 0d20230411}, {775480, 0d20230419}, ;
           {770463, 0d20230328}, {779978, 0d20230511}, {774188, 0d20230414}, {776455, 0d20230424}, {776454, 0d20230424}, ;
           {775475, 0d20230419}, {776563, 0d20230424}, {772322, 0d20230404}, {775148, 0d20230418}, {775731, 0d20230420}, ;
           {775732, 0d20230420}, {775733, 0d20230420}, {773648, 0d20230412}, {772863, 0d20230407}, {774853, 0d20230417}, ;
           {774855, 0d20230417}, {772323, 0d20230404}, {772324, 0d20230404}, {772325, 0d20230404}, {770380, 0d20230328}, ;
           {770381, 0d20230328}, {773403, 0d20230411}, {776954, 0d20230425}, {776955, 0d20230425}, {770365, 0d20230328}, ;
           {770368, 0d20230328}, {773708, 0d20230412}, {774927, 0d20230417}, {773393, 0d20230411}, {776871, 0d20230425}, ;
           {776874, 0d20230425}, {770084, 0d20230327}, {773647, 0d20230412}, {776549, 0d20230424}, {774186, 0d20230414}, ;
           {774231, 0d20230414}, {774235, 0d20230414}, {775952, 0d20230421}, {775953, 0d20230421}, {775980, 0d20230421}, ;
           {770037, 0d20230327}, {770040, 0d20230327}, {775118, 0d20230418}, {775119, 0d20230418}, {779033, 0d20230508}, ;
           {772862, 0d20230407}, {774230, 0d20230414}, {774232, 0d20230414}, {777183, 0d20230426}, {771938, 0d20230403}, ;
           {774874, 0d20230417}, {775785, 0d20230420}, {774187, 0d20230414}, {778978, 0d20230508}, {775474, 0d20230419}, ;
           {773642, 0d20230412}, {775120, 0d20230418}, {773598, 0d20230412}, {777112, 0d20230426}, {779615, 0d20230510}, ;
           {773632, 0d20230412}, {777138, 0d20230426}, {774298, 0d20230414}, {775956, 0d20230421}, {779894, 0d20230511}, ;
           {775801, 0d20230420}, {779675, 0d20230510}, {779841, 0d20230511}, {779842, 0d20230511}, {779893, 0d20230511}, ;
           {778323, 0d20230505}, {778909, 0d20230508}, {778892, 0d20230508}, {773743, 0d20230412}, {776618, 0d20230424}, ;
           {778117, 0d20230504}, {779067, 0d20230508}, {773633, 0d20230412}, {775429, 0d20230419}, {778893, 0d20230508}, ;
           {773604, 0d20230412}, {779968, 0d20230511}, {774209, 0d20230414}, {775428, 0d20230419}, {775433, 0d20230419}, ;
           {779552, 0d20230510}, {773596, 0d20230412}, {777139, 0d20230426}, {775430, 0d20230419}, {775437, 0d20230419}, ;
           {776600, 0d20230424}, {779037, 0d20230508}, {779553, 0d20230510}, {773749, 0d20230412}, {777184, 0d20230426}, ;
           {779614, 0d20230510}, {778995, 0d20230508}, {774148, 0d20230414}, {774149, 0d20230414}, {774150, 0d20230414}, ;
           {774152, 0d20230414}, {774154, 0d20230414}, {774155, 0d20230414}, {777237, 0d20230426}, {773689, 0d20230412}, ;
           {773646, 0d20230412}, {775436, 0d20230419}, {776810, 0d20230425}, {779932, 0d20230511}, {773709, 0d20230412}, ;
           {779979, 0d20230511}, {775730, 0d20230102}, {773630, 0d20230412}, {773642, 0d20230412}, {773710, 0d20230412}, ;
           {775120, 0d20230418}, {779039, 0d20230508}, {773603, 0d20230102}}

Local aSortedByNumber, aSortedByDate, aSortedByDateAndNumber

aSortedByNumber := ASort( aArray, , , { | x, y | x [ 1 ] < y [ 1 ] } )

msgdebug ( '1 SortedByNumber', aSortedByNumber )  

aSortedByDate := ASort( aArray, , , { | x, y | x [ 2 ] < y [ 2 ] } )

msgdebug ( '2 SortedByDate', aSortedByDate )

aSortedByDateAndNumber := ASort( aArray, , , { | x, y | x [ 2 ] < y [ 2 ] .And. x [ 1 ] < y [ 1 ] } )

msgdebug ( '3 SortedByDateAndNumber', aSortedByDateAndNumber )

RETURN
On my PC everything works as expected, but on some computers the same code, the same executable returns strange results. The resulting array is not sorted by date or number.
3.ByDateAndNumber-OK.png
3.ByDateAndNumber-OK.png (1011.05 KiB) Viewed 4515 times
3.ByDateAndNumber-NotOK.png
3.ByDateAndNumber-NotOK.png (997.2 KiB) Viewed 4515 times
I don't understand it at all, and I don't know what the problem is, I thought it might be a hardware problem, e.g. it is different on AMD and Intel (I had a similar case with rounding floating-point numbers in the times of clipper), but it behaves differently on the same processor family.

The second question is how to store a sorted array in a variable to be able to use it later in the code?
The example below doesn't work as I would like.

Code: Select all

#include "hmg.ch"

Function main()

Local aArray := { "B", "A", "C" }
Local aArrayAscend, aArrayDescend   

/* Why does changing the sort affect another array variable? 
   How to keep a sorted array variable for use later in the code? */

ASort ( aArray, , , { | x, y | x < y } )
aArrayAscend := aArray

msgdebug ( 'aArrayAscend', aArrayAscend, 'aArrayDescend', aArrayDescend, "aArrayAscend should be sorted ascending, aArrayDescend should be Nil")

ASort ( aArray, , , { | x, y | x > y } )
aArrayDescend := aArray

msgdebug ( 'aArrayAscend', aArrayAscend, 'aArrayDescend', aArrayDescend, "aArrayAscend should be sorted ascending, aArrayDescend should be sorted in descending order. Why is aArrayAscend equal to aArrayDescend?" )

RETURN
I would expect aArrayAscend to contain an ascending sorted array and aArrayDescend to contain a descending sorted array, but surprisingly they both have the same last sorted array, so ASort works by reference?

Re: Sorting arrays and storing them as variables.

Posted: Thu Sep 14, 2023 1:15 pm
by edk
I found a solution to my first problem: I converted the array data to a string and sort by string.

Code: Select all

aSortedByDateAndNumber := ASort( aArray, , , { | x, y | hb_TtoS( x [ 2 ] ) + StrZero ( x [ 1 ], 10 ) < hb_TtoS( y [ 2 ] ) + StrZero ( y [ 1 ], 10 ) } )
Now works on all computers. I wonder why the native solution doesn't work?

The second problem is still not solved.

Re: Sorting arrays and storing them as variables.

Posted: Thu Sep 14, 2023 1:31 pm
by edk
Solving the second issue (the dirty way):

Code: Select all

ASort ( aArray, , , { | x, y | x < y } )
aArrayAscend := &(hb_valToExp ( aArray ))

ASort ( aArray, , , { | x, y | x > y } )
aArrayDescend := &(hb_valToExp ( aArray ))
The question remains why ASort changes the order of values in other array variables.

Re: Sorting arrays and storing them as variables.

Posted: Thu Sep 14, 2023 2:13 pm
by branislavmil
Hello
Try this way:
...
aArrayAscend := aClone(aArray)
...

Re: Sorting arrays and storing them as variables.

Posted: Thu Sep 14, 2023 2:19 pm
by PeteWG
Hi,

regarding question 2:
aArrayAscend := AClone( ASort ( aArray, , , { | x, y | x < y } ) )
aArrayDescend := AClone( ASort ( aArray, , , { | x, y | x > y } ) )
// always use AClone to keep a copy of array to avoid any changes in original array to be "reflected" in your copy,
// because when you assigning an array to a variable in fact you assign references to its elements).

regards,
Pete

Re: Sorting arrays and storing them as variables.

Posted: Thu Sep 14, 2023 2:30 pm
by edk
PeteWG and branislavmil: thanks guys, I completely forgot about AClone :idea: :oops: