javascript 以与另一个数组相同的顺序对数组进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28377495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sort an array in the same order of another array
提问by BarryMode
I have a few arrays of 50+ names like this.
我有几个像这样的 50 多个名称的数组。
["dan", "ryan", "bob", "steven", "corbin"]
["bob", "dan", "steven", "corbin"]
I have another array that has the correct order. Note that the second array above does not include all of the names, but I still want it to follow the order of the following:
我有另一个具有正确顺序的数组。请注意,上面的第二个数组不包含所有名称,但我仍然希望它遵循以下顺序:
["ryan", "corbin", "dan", "steven", "bob"]
There is no logical order to it, they are just in this order. What makes sense to me is to compare each array against the correctly ordered one. I think I saw some people doing this with PHP, but I was not able to find a JavaScript solution. Does anyone have any idea how to do this? I've been trying for a few hours and I'm stumped.
它没有逻辑顺序,它们只是按照这个顺序。对我来说有意义的是将每个数组与正确排序的数组进行比较。我想我看到有些人用 PHP 做这件事,但我找不到 JavaScript 解决方案。有谁知道如何做到这一点?我已经尝试了几个小时,但被难住了。
回答by Barmar
Use indexOf()
to get the position of each element in the reference array, and use that in your comparison function.
使用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); // ["corbin", "dan", "steven", "bob"]
Searching the reference array every time will be inefficient for large arrays. If this is a problem, you can convert it into an object that maps names to positions:
对于大型数组,每次搜索参考数组将是低效的。如果这是一个问题,您可以将其转换为将名称映射到位置的对象:
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);
回答by alexpods
You can realize some sorter by patter factory function. Then create sorter using your pattern and apply it to your arrays:
您可以通过模式工厂功能实现某种排序器。然后使用您的模式创建排序器并将其应用于您的数组:
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) });
回答by Pawe?
I had the same issue now and I tried a bit different approach. It does not sort the arrays but filtering the order-list according to sorting-lists so it has got some limitations but for my needs it's event better because it gets rid of incorrect values from sorted list:
我现在遇到了同样的问题,我尝试了一些不同的方法。它不会对数组进行排序,而是根据排序列表过滤订单列表,因此它有一些限制,但对于我的需要,它更好,因为它从排序列表中删除了不正确的值:
- if sorting-list has got doubled value, it will occure just once in sorted list
- if sorting-list has got item which is not included in order-list, it will not appear in sorted 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/>';
回答by Eduard
If you need to place values of your array in the recurring order, meaning:
Input: [1, 2, 4, 4, 3, 3, 2, 1]
Output: [1, 2, 3, 4, 1, 2, 3, 4]
如果您需要按循环顺序放置数组的值,这意味着:
输入:[1, 2, 4, 4, 3, 3, 2, 1]
输出:[1, 2, 3, 4, 1, 2, 3, 4]
Then you can use 2 functions below. The first one uses the second one.
For the first function you will need to provide 2 arguments:
1st argument:your array of items that should be ordered (Inputfrom above)
2nd argument:array of the correct order ([1, 2, 3, 4]for the example above)
然后你可以使用下面的2个功能。第一个使用第二个。
对于第一个函数,您需要提供 2 个参数:
第一个参数:应该排序的项目数组(从上面输入)
第二个参数:正确顺序的数组([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;
}