按照与另一个数组相同的顺序对数组进行排序
Sort an array in the same order of another array
我有几个像这样的包含 50 多个名字的数组。
["dan", "ryan", "bob", "steven", "corbin"]
["bob", "dan", "steven", "corbin"]
我有另一个顺序正确的数组。请注意,上面的第二个数组不包括所有名称,但我仍然希望它遵循以下顺序:
["ryan", "corbin", "dan", "steven", "bob"]
没有逻辑顺序,就是这个顺序。对我来说有意义的是将每个数组与正确排序的数组进行比较。我想我看到有人用 PHP 这样做,但我找不到 JavaScript 解决方案。有谁知道如何做到这一点?我已经尝试了几个小时,但我很困惑。
使用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"]
每次都搜索参考数组对于大型数组来说效率很低。如果这是一个问题,您可以将其转换为将名称映射到位置的对象:
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);
你可以通过patter factory函数实现一些排序器。然后使用您的模式创建排序器并将其应用于您的数组:
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) });
我现在遇到了同样的问题,我尝试了一些不同的方法。
它不对数组进行排序,而是根据排序列表过滤顺序列表,因此它有一些限制,但对于我的需要来说,它更好,因为它从排序列表中删除了不正确的值:
- 如果 sorting-list 的值翻倍,它只会出现一次
排序列表
- if sorting-list 有项目不包括在
order-list,不会出现在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/>';
如果您需要按循环顺序放置数组的值,意思是:
输入:[1, 2, 4, 4, 3, 3, 2, 1]
输出:[1, 2, 3, 4, 1, 2, 3, 4]
那么您可以使用以下2个功能。第一个用第二个
对于第一个函数,您需要提供 2 个参数:
第一个参数: 您应该订购的项目数组(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;
}
我有几个像这样的包含 50 多个名字的数组。
["dan", "ryan", "bob", "steven", "corbin"]
["bob", "dan", "steven", "corbin"]
我有另一个顺序正确的数组。请注意,上面的第二个数组不包括所有名称,但我仍然希望它遵循以下顺序:
["ryan", "corbin", "dan", "steven", "bob"]
没有逻辑顺序,就是这个顺序。对我来说有意义的是将每个数组与正确排序的数组进行比较。我想我看到有人用 PHP 这样做,但我找不到 JavaScript 解决方案。有谁知道如何做到这一点?我已经尝试了几个小时,但我很困惑。
使用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"]
每次都搜索参考数组对于大型数组来说效率很低。如果这是一个问题,您可以将其转换为将名称映射到位置的对象:
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);
你可以通过patter factory函数实现一些排序器。然后使用您的模式创建排序器并将其应用于您的数组:
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) });
我现在遇到了同样的问题,我尝试了一些不同的方法。 它不对数组进行排序,而是根据排序列表过滤顺序列表,因此它有一些限制,但对于我的需要来说,它更好,因为它从排序列表中删除了不正确的值:
- 如果 sorting-list 的值翻倍,它只会出现一次 排序列表
- if sorting-list 有项目不包括在 order-list,不会出现在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/>';
如果您需要按循环顺序放置数组的值,意思是:
输入:[1, 2, 4, 4, 3, 3, 2, 1]
输出:[1, 2, 3, 4, 1, 2, 3, 4]
那么您可以使用以下2个功能。第一个用第二个
对于第一个函数,您需要提供 2 个参数:
第一个参数: 您应该订购的项目数组(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;
}