Keith Joubert logo - home.

Home
Contact

Binary Search
Sort Multiple Columns
Filing Functions
Extracting Excel data
Read and Write .csv files
Show Progress Messages
Send Automatic Email
Running under .hta
Setting Folder Attributes
Long-script warnings
Desktop Shortcut
ADODB & SQL queries

 

 
SORT  SINGLE- & MULTI-DIMENSIONAL ARRAYS

Javascript has an efficient built-in algorithm in its sort() function.  However, this only sorts lexicographically.  Therefore, an additional, purpose-built function is required to handle particular data types,

The SortIt() function uses the Javascript sort() function to sort single- or multiple-dimensioned arrays (columns) in numerical/alphnumerical order, with numerals first.  An alphanumical example would be, say,  'TY6VB98'.  This type of data is sorted lexicographically.   In a recent application, arrays involving up to 10 columns of data and 250kB of data had to be sorted.  In this case, the greatest required depth turned out to be a sort on 6 columns.  SortIt() does this pretty quickly.

/*
This example of SortIt is set up for six columns of multi-dimensional array, in column order of u,v,w,x,y,z  (column numbers).  Edit the code to reduce or increase the maximum columns allowed, to suit your use.  Note that the sort will only continue as far as the specified number of columns in the call, ie,  "w,x" only sorts on two columns, etc.
SortIt will place numbers before strings, and swap until all columns are in ascending order, with precedence specified by the column order of the call.

To get sort in descending order, use the standard function: TheArr.reverse(), after the sort.

One can shorten or lengthen the function according to the number of columns that it is desired to sort.
One could also use recursion to do the multiple ops, or use an internal function.  I left it this way for clarity, to avoid setting variables, for speed, and because my application's javascript involved some 5000 lines of code, anyway.

 
FOR EXAMPLE, BEFORE SORT (The example indicates a four-column sort)

An array of  [Bay  ,  Style  ,  Size  ,  Quantity] arrays
as in :
myArr[0][BB-87,31256,5,78];
myArr[1][AE-76,1-11123,2h,45];
etc.....:
3RD Fl,2351,12,456
DA-65,4521,4h,45
UY-32,1-785,7,210
3RD Fl,2351,5,85
ZZ-65,M4548,6h,21
3RD Fl,2351,12,21

SortIt(Arr,1,2,3,0); <----Columns: sort on Style, Size, Quantity, Bay

Arr out =
3RD Fl,2351,5,85
3RD Fl,2351,12,21
3RD Fl,2351,12,456
DA-65,4521,4h,45
BB-87,31256,5,78
AE-76,1-11123,2h,45
UY-32,1-785,7,210
ZZ-65,M4548,6h,21

Then, for comparison: sort on Bay, etc

SortIt(Arr,0,1,2,3);

Arr out =
3RD Fl,2351,5,85
3RD Fl,2351,12,21
3RD Fl,2351,12,456
AE-76,1-11123,2h,45
BB-87,31256,5,78
DA-65,4521,4h,45
UY-32,1-785,7,210
ZZ-65,M4548,6h,21

*/

// GENERAL SORT FUNCTION:
// Sort on single or multi-column arrays.
// Sort set up for six colums, in order of u,v,w,x,y,z.   For single columns (single-dimensioned array), omit all u,v....
// Sort will continue only as far as the specified number of columns: "w,x" only sorts on two columns, etc.
// Sort will place numbers before strings, and swap until all columns are in ascending order.
// Sorter algorithm:
// Is result of a-b NaN?.  Then one or both is text.
//   Are both text?  Then do a general swap. Set var 'swap' to 1:0:-1, accordingly: 1 push up list, -1 push down.
//   Else one is text, the other a number.  Therefore, is 'a' text?  Then push up, else 'b' is text - push 'a' down.
// Else both are numbers.
// return result in var 'swap'.
// To do multi-columns, repeat the operations for each column.
// To do ascending.descending, asending, etc columns, see the code further down the page.

function SortIt(TheArr,u,v,w,x,y,z){

  if(u==undefined){TheArr.sort(Sortsingle);} // this is a simple array, not multi-dimensional, ie, SortIt(TheArr);
  else{TheArr.sort(Sortmulti);}

  function Sortsingle(a,b){
    var swap=0;
    if(isNaN(a-b)){
      if((isNaN(a))&&(isNaN(b))){swap=(b<a)-(a<b);}
      else {swap=(isNaN(a)?1:-1);}
    }
    else {swap=(a-b);}
    return swap;
  }

 function Sortmulti(a,b){
  var swap=0;
    if(isNaN(a[u]-b[u])){
      if((isNaN(a[u]))&&(isNaN(b[u]))){swap=(b[u]<a[u])-(a[u]<b[u]);}
      else{swap=(isNaN(a[u])?1:-1);}
    }
    else{swap=(a[u]-b[u]);}
    if((v==undefined)||(swap!=0)){return swap;}
    else{
      if(isNaN(a[v]-b[v])){
        if((isNaN(a[v]))&&(isNaN(b[v]))){swap=(b[v]<a[v])-(a[v]<b[v]);}
        else{swap=(isNaN(a[v])?1:-1);}
      }
      else{swap=(a[v]-b[v]);}
      if((w==undefined)||(swap!=0)){return swap;}
      else{
        if(isNaN(a[w]-b[w])){
          if((isNaN(a[w]))&&(isNaN(b[w]))){swap=(b[w]<a[w])-(a[w]<b[w]);}
          else{swap=(isNaN(a[w])?1:-1);}
        }
        else{swap=(a[w]-b[w]);}
        if((x==undefined)||(swap!=0)){return swap;}
        else{
          if(isNaN(a[x]-b[x])){
            if((isNaN(a[x]))&&(isNaN(b[x]))){swap=(b[x]<a[x])-(a[x]<b[x]);}
            else{swap=(isNaN(a[x])?1:-1);}
          }
          else{swap=(a[x]-b[x]);}
          if((y==undefined)||(swap!=0)){return swap;}
          else{
            if(isNaN(a[y]-b[y])){
              if((isNaN(a[y]))&&(isNaN(b[y]))){swap=(b[y]<a[y])-(a[y]<b[y]);}
              else{swap=(isNaN(a[y])?1:-1);}
            }
            else{swap=(a[y]-b[y]);}
            if((z=undefined)||(swap!=0)){return swap;}
            else{
              if(isNaN(a[z]-b[z])){
                if((isNaN(a[z]))&&(isNaN(b[z]))){swap=(b[z]<a[z])-(a[z]<b[z]);}
                else{swap=(isNaN(a[z])?1:-1);}
              }
              else{swap=(a[z]-b[z]);}
              return swap;
} } } } } } }

 

// Should you wish to sort in mixed ascending/descending sort order (say col'm 0 ascending, col'm 1, descending,
// other columns also mixed...), the following code  applies.

// Note: If you then wish to do a binary search on a reverse-sorted column, you'd have to reverse the array prior to
// using BinSearch().

 
function SortIt(TheArr,us,u,vs,v,ws,w,xs,x,ys,y,zs,z){
// us-zs: 1=asc, -1=desc.  u-z: column-numbers.  See example

  if(u==undefined){TheArr.sort(Sortsingle);} // if this is a simple array, not multi-dimensional, ie, SortIt(TheArr,1): ascending.
  else{TheArr.sort(Sortmulti);}

  function Sortsingle(a,b){
    var swap=0;
    if(isNaN(a-b)){
      if((isNaN(a))&&(isNaN(b))){swap=(b<a)-(a<b);}
      else {swap=(isNaN(a)?1:-1);}
    }
    else {swap=(a-b);}
    return swap*us;
  }

  function Sortmulti(a,b){
  var swap=0;
    if(isNaN(a[u]-b[u])){
      if((isNaN(a[u]))&&(isNaN(b[u]))){swap=(b[u]<a[u])-(a[u]<b[u]);}
      else{swap=(isNaN(a[u])?1:-1);}
    }
    else{swap=(a[u]-b[u]);}
    if((v==undefined)||(swap!=0)){return swap*us;}
    else{
      if(isNaN(a[v]-b[v])){
        if((isNaN(a[v]))&&(isNaN(b[v]))){swap=(b[v]<a[v])-(a[v]<b[v]);}
        else{swap=(isNaN(a[v])?1:-1);}
      }
      else{swap=(a[v]-b[v]);}
      if((w==undefined)||(swap!=0)){return swap*vs;}
      else{
        if(isNaN(a[w]-b[w])){
          if((isNaN(a[w]))&&(isNaN(b[w]))){swap=(b[w]<a[w])-(a[w]<b[w]);}
          else{swap=(isNaN(a[w])?1:-1);}
        }
        else{swap=(a[w]-b[w]);}
        if((x==undefined)||(swap!=0)){return swap*ws;}
        else{
          if(isNaN(a[x]-b[x])){
            if((isNaN(a[x]))&&(isNaN(b[x]))){swap=(b[x]<a[x])-(a[x]<b[x]);}
            else{swap=(isNaN(a[x])?1:-1);}
          }
          else{swap=(a[x]-b[x]);}
          if((y==undefined)||(swap!=0)){return swap*xs;}
          else{
            if(isNaN(a[y]-b[y])){
              if((isNaN(a[y]))&&(isNaN(b[y]))){swap=(b[y]<a[y])-(a[y]<b[y]);}
              else{swap=(isNaN(a[y])?1:-1);}
            }
            else{swap=(a[y]-b[y]);}
            if((z=undefined)||(swap!=0)){return swap*ys;}
            else{
              if(isNaN(a[z]-b[z])){
                if((isNaN(a[z]))&&(isNaN(b[z]))){swap=(b[z]<a[z])-(a[z]<b[z]);}
                else{swap=(isNaN(a[z])?1:-1);}
              }
              else{swap=(a[z]-b[z]);}
              return swap*zs;
} } } } } } }

 

To test the ascending/descending code, I used the following:

TestArr=new Array([2,8,1,'BAS',5,9],[5,1,2,'DES',1,5],[5,9,1,'GOL',8,3],[8,2,2,'NUY',4,7],[5,7,2,'VIC',2,2],[6,7,8,'ABL',4,1],
            [5,9,1,'KHF',8,3],[8,2,0,'MOYT',8,1],[5,0,3,'AVGR',7,2],[5,8,2,'MU89',7,5]); 
// This array needs many more elements to illustrate the function well.  Preferably use real data...

document.write('<BR>Un-Sorted:<BR><BR>');
for(var i=0;i<10;i++){document.write(TestArr[i]+'<BR>');}
SortIt(TestArr,1,0,-1,1,1,2,-1,3);;
document.write('<BR>Sorted: 4 col in order: 0,1,2,3 in order: asc, desc, asc, des<BR><BR>');
for(var i=0;i<10;i++){document.write(TestArr[i]+'<BR>');}

SortIt(TestArr,1,2,-1,1,-1,3,1,0,-1,5,1,4);
document.write('<BR>Sorted: 6 col in order: 2,1,3,0,5,4 in order: asc, desc, desc, asc, desc, asc<BR><BR>');
for(var i=0;i<10;i++){document.write(TestArr[i]+'<BR>');}

// Click here to see the results of these tests.


TopTop