2015-03-06 4 views
1

У меня есть массив, который имеет следующие значенияКак отсортировать массив на основе значений другого массива?

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 

Я хочу, чтобы сгруппировать их на основе следующих массива [ 'AD8', 'CD3', 'DD2', 'PD0']; и сортировать каждую группу на основе количества каждого значения. Таким образом, выход должен быть

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 

До сих пор, я написал следующий код, но он не работает должным образом, и я застрял здесь.

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; 
      } 
     }   
    } 
} 
+2

Является ли, что сортировка массива 'filterArray' себя намеренно в алфавитном порядке, или это просто совпадение? – Alnitak

+0

@Alnitak этот массив ['AD8', 'CD3', 'DD2', 'PD0'] намеренно отсортирован. – Jack

+0

@Jack и суффиксы всегда в формате '_XXN_NN'? – Alnitak

ответ

1

На том основании, что массив фильтрации находится в алфавитном порядке, и что каждая строка имеет подстроки в формате _XXN_NN_, что вы на самом деле хотите, чтобы разобраться, то это должно быть достаточно просто разобраться в извлечении этой подстроки без ссылки на 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);

+0

Прошу прощения, я должен был упомянуть, что строка будет длиннее. – Jack

+0

Я думаю, что OP хочет сначала сортировать по b, затем a. Посмотрите, как Алекс предшествует Наташе – Sphaso

+0

@Sphaso, это прекрасно, так как он сортируется на '01', а также' PO'. Тем не менее, дополнительные биты на конце нуждаются в некоторой работе! – Alnitak

1

Использование первого sort параметра вы можете передать functi для запуска сортировки массива. Эта функция получает 2 значения массива и должна сравнивать их и возвращать меньше 0, если первая меньше второй, выше 0, если она выше, или 0, если они одинаковы. В моем предложении я разделил имя и «токен» часть значений, а затем сравнил токены, чтобы упорядочить их правильно. Использование indexOf на filterArray позволяет мне соответственно сравнить положение тегов.

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: Этот метод сортировки таким образом, что filterArray может быть в любом порядке, и диктует порядок хотел. После обновлений от OP это может и не быть требованием ... EDIT2: вопрос все больше меняется, это решение не будет работать.

1

Мое решение. Единственное ограничение, которое имеет это решение, состоит в том, что ваш массив сортировки должен быть отсортирован уже. Часть XXn_nn может быть в любом месте в строке, но предполагает, что часть nn всегда следует за частью XXn (например, 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); 
} 

И работает fiddle

Смежные вопросы