FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour aSort on two fields
Posts: 2706
Joined: Fri Oct 07, 2005 01:50 PM
aSort on two fields
Posted: Wed Aug 12, 2015 04:48 PM
To All

I need to sort an array by two fields .. first by C then by A .. looking at the aSort docs it appears you can only sort on one field and not a concatenation of two. Hopefully I am wrong and someone can give me some advice on sorting this array first on C then on A ..
Code (fw): Select all Collapse
aSort( aBitem,,, {|x,y| x[3] < y[3]} )


Thanks
Rick Lipkin
Posts: 1283
Joined: Fri Feb 10, 2006 02:34 PM
Re: aSort on two fields
Posted: Wed Aug 12, 2015 04:55 PM

Rick

Maybe u can try aSort( aBitem,,, {|x,y| x[3] + x[1] < y[3] + y[1]} ). If field 3 is numeric u need to do aSort( aBitem,,, {|x,y| str(x[3],3) + x[1] < str(y[3],3) + y[1]} )

Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
HIX -> https://github.com/carles9000/hix
Posts: 2706
Joined: Fri Oct 07, 2005 01:50 PM
Re: aSort on two fields
Posted: Wed Aug 12, 2015 05:04 PM

Charles

I thought about adding them together .. but ( for me ) when I did, it did not work .. but your code works !

Thanks
Rick Lipkin

Posts: 389
Joined: Mon Oct 13, 2008 11:26 AM
Re: aSort on two fields
Posted: Thu Aug 13, 2015 11:21 AM
What type is in these fields?
The best way to do this is converting both to text of the same size.

Ex:
Code (fw): Select all Collapse
//-- 1: Code, 2: Last Name, 3: First Name
aBitem := {}
aAdd( aBItem, {1, PadR( "FIELDS", 25 ), PadR("ROBERT",20) } )
aAdd( aBItem, {2, PadR( "BARROW", 25 ), PadR("SARAH",20) } )
aAdd( aBItem, {3, PadR( "FIELDS", 25 ), PadR("ANTHONY",20) } )

//-- Sort by last name
aSort( aBitem,,, {|x,y| ( x[2]+x[3] ) < ( y[2]+y[3] ) } )

? AllTrim( aBItem[1,2] ) + AllTrim( aBItem[1,3] ) //-- BARROW SARAH
? AllTrim( aBItem[2,2] ) + AllTrim( aBItem[2,3] ) //-- FIELDS ANTHONY 
? AllTrim( aBItem[3,2] ) + AllTrim( aBItem[3,3] ) //-- FIELDS ROBERT

//-- Sort by first name
aSort( aBitem,,, {|x,y| ( x[3]+x[2] ) < ( y[3]+y[2] ) } )

? AllTrim( aBItem[1,3] ) + AllTrim( aBItem[1,2] ) //-- ANTHONY FIELDS  
? AllTrim( aBItem[2,3] ) + AllTrim( aBItem[2,2] ) //-- ROBERT FIELDS 
? AllTrim( aBItem[3,3] ) + AllTrim( aBItem[3,2] ) //-- SARAH BARROW 

//-- Sort by code
aSort( aBitem,,, {|x,y| ( x[1] ) < ( y[1] ) } )

? AllTrim( aBItem[1,3] ) + AllTrim( aBItem[1,2] ) //-- ROBERT FIELDS
? AllTrim( aBItem[2,3] ) + AllTrim( aBItem[2,2] ) //-- SARAH BARROW 
? AllTrim( aBItem[3,3] ) + AllTrim( aBItem[3,2] ) //-- ANTHONY FIELDS
Email: SamirSSabreu@gmail.com
xHarbour 1.2.3 + Fwhh 20.2
Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Re: aSort on two fields
Posted: Tue Aug 18, 2015 07:03 AM
To avoid dealing with type, a 'type agnostic' comparision function can be used, like
Code (fw): Select all Collapse
{|x,y| if( x[3] == y[3], x[1] < y[1], x[3] < y[3] ) }

no type convertion nor concatenation required.
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
Re: aSort on two fields
Posted: Tue Aug 18, 2015 01:53 PM
Rick,

You could also do it by using a temp DBF (in memory) instead of an array as discussed here:

http://forums.fivetechsupport.com/viewtopic.php?f=3&t=31054

You can use an index too.

I haven't tried it yet, so I can't give more specifics.

James
FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 2706
Joined: Fri Oct 07, 2005 01:50 PM
Re: aSort on two fields
Posted: Tue Aug 18, 2015 07:43 PM

James

Thanks and to everyone else .. I was intrigued with Carlos solution and will give it a try .. for now, adding the two elements together has worked.

Rick Lipkin

Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: aSort on two fields
Posted: Fri Aug 21, 2015 08:38 AM
Carlos Mora wrote:To avoid dealing with type, a 'type agnostic' comparision function can be used, like
Code (fw): Select all Collapse
{|x,y| if( x[3] == y[3], x[1] < y[1], x[3] < y[3] ) }

no type convertion nor concatenation required.


I too use this logic.
Regards



G. N. Rao.

Hyderabad, India

Continue the discussion