Jack
Jack

Reputation: 6600

How to sort an array based on values of another array?

I have an array that has following values

Nata_sha_AD8_02_ABA
Jack_DD2_03_K
Alex_AD8_01_PO
Mary_CD3_03_DC
John_DD2_01_ER
Daniel_AD8_04_WS

I want to group them based on following array ['AD8','CD3','DD2','PD0']; and sort each group based on number of each value. So the output should be

Alex_AD8_01_PO
Nata_sha_AD8_02_ABA 
Daniel_AD8_04_WS
Mary_CD3_03_DC
John_DD2_01_ER
Jack_DD2_03_K

So far, I wrote following code, but it does not work properly, and I am stuck here.

var temparr = [];
var order = 1000;
var pos = -1;
var temp = -1;
var filterArray= ['AD8','CD3','DD2','PD0'];
 for (i =0; i< filterArray.length; i++) {
    for (j =0; j < myarray.length; j++) {
        if(filterArray[i].toUpperCase().search(myarray[j])>0){
          temp = str.substring(myarray[j].indexOf(filterArray[i])+4, myarray[j].indexOf(filterArray[i]+6); 
          if(temp < order){
            pos = j;
            order = temp;
          }
          if(j == myarray.length-1){ //reached end of the loop
              temparr.push(myarray[pos]);
              order = 1000;
          }
        }        
    }
 }

Upvotes: 1

Views: 81

Answers (3)

Alnitak
Alnitak

Reputation: 339786

On the basis that the filtering array is in alphabetical order, and that every string has a substring in the format _XXN_NN_ that you actually want to sort on, it should be sufficient simply to sort based on extracting that substring, without reference to filterArray:

var names = ['Nata_sha_AD8_02_ABA', 'Jack_DD2_03_K', 'Alex_AD8_01_PO', 'Mary_CD3_03_DC', 'John_DD2_01_ER', 'Daniel_AD8_04_WS'];

names.sort(function(a, b) {
  var re = /_((AD8|CD3|DD2|PD0)_\d\d)_/;
  a = a.match(re)[1];
  b = b.match(re)[1];
  return a.localeCompare(b);
});

alert(names);

Upvotes: 1

Michel
Michel

Reputation: 4157

My solution. The only restriction this solution has has is that your sort array has to be sorted already. The XXn_nn part can be anywhere in the string, but it assumes the nn part always follows the XXn part (like DD3_17).

var result=new Array();
var p,x;

    //loop the 'search' array
for(var si=0,sl=sort.length;si<sl;si++){

    //create new tmp array
    var tmp=new Array();

    //loop the data array
    for(var ai=0,al=arr.length;ai<al;ai++){
        var el=arr[ai];
        //test if element still exists
        if(typeof el=='undefined' || el=='')continue;

        //test if element has 'XXn_nn' part 
        if(arr[ai].indexOf(sort[si]) > -1){
            //we don't now where the 'XXn_nn' part is, so we split on '_' and look for it
            x=el.split('_');
            p=x.indexOf(sort[si]);
            //add element to tmp array on position nn
            tmp[parseInt(x[p+1])]=el;
            //remove element from ariginal array, making sure we don't check it again
            arr.splice(ai,1);ai--;
            }
    }
    //remove empty's from tmp array
    tmp=tmp.filter(function(n){return n!=undefined}); 
    //add to result array
    result=result.concat(tmp);
}

And a working fiddle

Upvotes: 1

Salketer
Salketer

Reputation: 15711

Using the first sort parameter you can pass a function to run to sort the array. This function receives 2 values of the array, and should compare them and return less than 0 if the first is lower than the second, higher than 0 if it is higher, or 0 if they are the same. In my proposition, I split the name and "token" part of the values, and then compare the tokens to order them correctly. Using the indexOf on the filterArray allows me to compare the position of the tags accordingly.

var array_to_sort = ['Natasha_AD8_02',
  'Jack_DD2_03',
  'Alex_AD8_01',
  'Mary_CD3_03',
  'John_DD2_01',
  'Daniel_AD8_04'
];

var filterArray = ['AD8', 'CD3', 'DD2', 'PD0'];

array_to_sort.sort(function(a, b) {
  a_token = a.substr(a.indexOf('_')+1); //Remove the name part as it is useless
  b_token = b.substr(b.indexOf('_')+1);//Remove the name part as it is useless
  if(a_token.substr(0,3) == b_token.substr(0,3)){//If the code is the same, order by the following numbers
    if(a_token > b_token){return 1;}
    if(a_token < b_token){return -1;}
    return 0;
  }else{ //Compare the position in the filterArray of each code.
    if(filterArray.indexOf(a_token.substr(0,3)) > filterArray.indexOf(b_token.substr(0,3))){return 1;}
    if(filterArray.indexOf(a_token.substr(0,3)) < filterArray.indexOf(b_token.substr(0,3))){return -1;}
    return 0;
  }
});


document.write(array_to_sort);

EDIT: This method will sort in a way that the filterArray can be in any order, and dictates the order wanted. After updates from OP this may not be the requirement... EDIT2: the question being modified more and more, this solution will not work.

Upvotes: 1

Related Questions