Reputation: 6600
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
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
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
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