2015-02-07 4 views
2

У меня есть несколько массивов из 50+ имен, подобных этому.Javascript: сортировать массив в том же порядке другого массива

["dan", "ryan", "bob", "steven", "corbin"]

["bob", "dan", "steven", "corbin"]

У меня есть еще один массив, который имеет правильный порядок. Обратите внимание, что второй массив выше, не включают в себя все имена, но я все еще хочу, чтобы следить за тем, следующее:

["ryan", "corbin", "dan", "steven", "bob"]

Там нет логического порядка в ней, они просто в этом порядке , Для меня имеет смысл сравнить каждый массив с правильно упорядоченным. Я думаю, что я видел, как некоторые люди делали это с PHP, но я не смог найти решение для javascript. Кто-нибудь знает, как это сделать? Я пробовал несколько часов, и я в тупике.

+0

Есть ли по какой причине вы хотите, чтобы они были в этом порядке? Если вы просто хотите, чтобы они были в том же * порядке, вы можете просто использовать '.sort()' на обоих массивах. – Aweary

ответ

15

Используйте indexOf(), чтобы получить положение каждого элемента в массиве ссылок и использовать его в вашей функции сравнения.

var reference_array = ["ryan", "corbin", "dan", "steven", "bob"]; 
 
var array = ["bob", "dan", "steven", "corbin"]; 
 
array.sort(function(a, b) { 
 
    return reference_array.indexOf(a) - reference_array.indexOf(b); 
 
}); 
 
console.log(array);

Поиск эталонного массива каждый раз, когда будет неэффективен для больших массивов. Если это проблема, вы можете преобразовать его в объект, который отображает имена позиций:

var reference_array = ["ryan", "corbin", "dan", "steven", "bob"]; 
 
reference_object = {}; 
 
for (var i = 0; i < reference_array.length; i++) { 
 
    reference_object[reference_array[i]] = i; 
 
} 
 
var array = ["bob", "dan", "steven", "corbin"]; 
 
array.sort(function(a, b) { 
 
    return reference_object[a] - reference_object[b]; 
 
}); 
 
console.log(array);

+0

Это работает и отвечает на вопрос, который я задал. Я задал вопрос, не сказав, что мой оригинальный массив был фактически объектом. Чтобы исправить это, мне удалось получить ключи от объекта с помощью '_.keys', затем я смог отсортировать их с помощью вашего метода' reference_array.indexOf (a) - reference_array.indexOf (b); ' I задал второй вопрос с моим точным кодом (http://stackoverflow.com/questions/28395477/javascript-sorting-parsed-json-within-each-loop), но в конце концов мне пришлось выяснить преобразование объекта в массив. Я использовал этот ответ и тот, чтобы окончательно решить мою проблему сортировки. – BarryMode

+0

Не забывайте отмечать свои вопросы с помощью 'underscorejs', если вас интересуют решения, использующие эту библиотеку. – Barmar

0

Вы можете реализовать некоторый сортировщик по функции скороговорки фабрики. Затем создайте сортировщик с помощью рисунка и примените его к вашим массивам:

function sorterByPattern(pattern) { 
    var hash = {}; 
    pattern.forEach(function(name, index) { hash[name] = index }); 

    return function(n1, n2) { 
     if (!(n1 in hash)) return 1; // checks if name is not in the pattern 
     if (!(n2 in hash)) return -1; // if true - place that names to the end 
     return hash[n1] - hash[n2]; 
    } 
} 

var sorter = sorterByPattern(["ryan", "corbin", "dan", "steven", "bob"]); 

var arrays = [ 
    ["dan", "ryan", "bob", "steven", "corbin"], 
    ["bob", "dan", "steven", "corbin"] 
    /* ... */ 
]; 

arrays.forEach(function(array) { array.sort(sorter) }); 
0

У меня была такая же проблема сейчас, и я попробовал немного другой подход. Это не сортирует массивы, но фильтровать заказ-список согласно сортировочных спискам, так что имеют некоторые ограничения, но для моих потребностей этого событие лучше, потому что он избавляется от неправильных значений из отсортированного списка:

  • если сортировка -list имеет удвоенное значение, оно будет больше появляться только один раз в отсортированного списка
  • если сортировочно-лист получил товар, который не входит в порядке-списке, он не будет отображаться в списке отсортированных

function sortOrder(getOrder,getArr){ 
 
    return getOrder.filter(function(order){ 
 
    return getArr.some(function(list){ 
 
     return order === list; 
 
    }); 
 
    }); 
 
} 
 

 
//arrays 
 
var order = ["ryan", "corbin", "dan", "steven", "bob"]; 
 
var arA = ["dan", "ryan", "bob", "steven", "corbin"]; 
 
var arB = ["bob", "dan", "steven", "corbin"]; 
 
var arC = ["bob","ryan"]; 
 
var arD = ["bob","bob","corbin"]; //remove repetition 
 
var arE = ["unrecognizedItem","corbin","steven","ryan"]; //remove the item not included in order array 
 

 
//print results 
 
document.body.innerHTML = sortOrder(order,arA)+'<br/>'; 
 
document.body.innerHTML += sortOrder(order,arB)+'<br/>'; 
 
document.body.innerHTML += sortOrder(order,arC)+'<br/>'; 
 
document.body.innerHTML += sortOrder(order,arD)+'<br/>'; 
 
document.body.innerHTML += sortOrder(order,arE)+'<br/>';

0

Если вам необходимо поместить значения вашего массива в повторяющейся порядке, а это означает:
Input: [1, 2, 4, 4, 3, 3, 2, 1]
Выход: [1 , 2, 3, 4, 1, 2, 3, 4]

Затем вы можете использовать 2 функции ниже. Первый использует второй.
Для первой функции вам нужно будет предоставить 2 аргумент:
1-й аргумент: вашего массив элементов, которые должны быть заказаны (Input сверху)
второго аргумента: массива в правильном порядке ([1, 2, 3, 4] для примера выше)

function sortByOrder (array, order) { 

    const arrayOfArrays = order.map(v => { 

     return [...Array(howMany(v, array))].map(undef => v); 
    }); 

    const tempArray = []; 

    arrayOfArrays.forEach((subArr, i) => { 

     let index = order.indexOf(order[i]); 

     subArr.forEach(duplicate => { 

      tempArray[index] = duplicate; 

      index += order.length; 
     }); 
    }); 

    return tempArray.filter(v => v); 
} 

function howMany(value, array) { 

     const regExp = new RegExp(value, 'g'); 

     return (array.join(' ').match(regExp) || []).length; 
} 
Смежные вопросы