简体   繁体   English

根据javascript中的另一个数组对数组进行排序

[英]sort array based on another array in javascript

I have two arrays: 我有两个数组:

const originalArray = ['a', 'n', 'u', 'b', 'd', 'z'];

const sortOrder = ['n', 'z'];

so I want output as ['n', 'z', 'a', 'u', 'b', 'd']; 所以我想输出为['n', 'z', 'a', 'u', 'b', 'd'];

basically the order of originalArray sorted by the order of secondArray. 基本上,originalArray的顺序按secondArray的顺序排序。

I can popOut the elements from the original array based on second array and then can append them in front and this will give me the desired solution, but not sure if that would be efficient or is there any better way to do it using array.sort(fxn) ; 我可以从基于第二个数组的原始数组中弹出元素,然后可以将它们附加在前面,这将为我提供所需的解决方案,但不确定是否有效,或者是否有更好的方法使用array.sort(fxn) ;

const originalArray = ['a', 'n', 'u', 'b', 'd', 'z'];

const sortOrder = ['n', 'z'];
const reverseOrder = sortOrder.reverse();
for (let elem of reverseOrder) {
const indexofelem = originalArray.indexOf(elem);
 originalArray.unshift(originalArray.splice(indexofelem, 1)[0]);
}

console.log(originalArray);

You can create a sort function based on the matching index in the sortOrder array. 您可以基于sortOrder数组中的匹配索引创建排序函数。

 const originalArray = ['a', 'n', 'u', 'b', 'd', 'z']; const sortOrder = ['n', 'z']; function sortArrays(a, b) { var indexOfA = sortOrder.indexOf(a), indexOfB = sortOrder.indexOf(b); if (indexOfA == -1) { indexOfA = sortOrder.length + 1; } if (indexOfB == -1) { indexOfB = sortOrder.length + 1; } if (indexOfA < indexOfB) { return -1; } if (indexOfA > indexOfB) { return 1; } return 0; } originalArray.sort(sortArrays); console.log(originalArray); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

You could use an object for the position of the items or take a default value of zero for calculating the delta. 您可以将一个对象用于项目的位置,或者将默认值零用于计算增量。

With a delta of zero, a stable sort is not granted. 如果增量为零,则不会授予稳定的排序。

 const array = ['a', 'n', 'u', 'b', 'd', 'z'], sortOrder = ['n', 'z'], order = sortOrder.reduce((r, a, i, aa) => (r[a] = -aa.length + i, r), {}); array.sort((a, b) => (order[a] || 0) - (order[b] || 0)); console.log(array); console.log(order); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

For a stable sort, you could use sorting with map with an object, which keeps the index and the group for the values with priority. 为了实现稳定的排序,可以对带有对象的map进行排序 ,这样可以使索引和值的组优先。 Inside of a group, the sort order is maintained by the index of the original array. 在组内部,排序顺序由原始数组的索引维护。

 // the array to be sorted var list = ['a', 'n', 'u', 'b', 'd', 'z'], sortOrder = ['n', 'z'], order = sortOrder.reduce((r, a, i, aa) => (r[a] = -aa.length + i, r), {}); // temporary array holds objects with position and sort-value var mapped = list.map(function (el, i) { return { index: i, group: order[el] || 0 }; }); // sorting the mapped array containing the reduced values mapped.sort(function (a, b) { return a.group - b.group || a.index - b.index; }); // container for the resulting order var result = mapped.map(function (el) { return list[el.index]; }); console.log(result); 

For large data array handling we can use object mapping 对于大数据数组处理,我们可以使用对象映射

var originalArray = ['a', 'n', 'u', 'b', 'd', 'z'],
sortOrder = ['n', 'z'];
var result = {};
var finalResponse = [];

// loop over item array which have to sort
originalArray.forEach(function(elem) {
  // if element not persent in result object then create map with true flag set
  if(!result[elem]){
    result[elem] = true
  }
});

// loop over sort order to check element exist in given array
sortOrder.forEach(function(elem) {
  //if element exist then push to array data and set flag to false for element matched.
  if(result[elem]){
    finalResponse.push(elem);
    result[elem] = false
  }
});

// loop over final object data and find all element with true value
for(var key in result) {
  if(result[key]){
   finalResponse.push(key);
  }
}
console.log('final response ',finalResponse);

If you require a stable sort (ie you want the elements not in the sortOrder array to keep their original order), you can combine two sort maps using Object.assign and an offset. 如果您需要稳定的排序(即,希望不在sortOrder数组中的元素保持其原始顺序),则可以使用Object.assign和offset组合两个排序图。

So, to make sure our sort is stable, we combine two maps: - a map of the original indexes, starting at the length of the data and going to 1 - a map of the defined indexes, offset by the length of the data 因此,为确保排序稳定,我们合并了两个映射:-原始索引的映射,从数据的长度开始,一直到1-定义索引的映射,被数据的长度偏移

 // Create a map that holds an integer sort index for // each value in an array based on its index const sortMap = (ref, offset = 0) => ref.reduce((map, x, i) => Object.assign(map, { [x]: (ref.length - i) + offset }) , {}); // Returns a function that sorts based on a value in a map const sortWithMap = map => (a, b) => (map[b] || 0) - (map[a] || 0); const originalArray = "abcdefghijlmnopqrstuvwxyz".split(""); const sortOrder = ['n', 'z']; const sortToOrder = (order, data) => data.sort( sortWithMap(sortMap(order)) ); const sortToOrderStable = (order, data) => data.sort( sortWithMap(Object.assign( sortMap(data), sortMap(order, data.length) ))); console.log("Stable:", JSON.stringify( sortToOrderStable(sortOrder, originalArray) ) ); console.log("Default:", JSON.stringify( sortToOrder(sortOrder, originalArray) ) ); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM