按照与另一个数组相同的顺序对数组进行排序

时间:2015-02-07 01:25:15

标签: javascript sorting compare

我有几个像这样的50多个名字的数组。

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

我有另一个具有正确顺序的数组。请注意,上面的第二个数组不包含所有名称,但我仍然希望它遵循以下顺序:

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

它没有逻辑顺序,它们只是按此顺序排列。对我来说有意义的是将每个数组与正确排序的数组进行比较。我想我看到有些人用PHP做这件事,但我找不到JavaScript解决方案。有谁知道怎么做?我已经尝试了几个小时而且我很难过。

4 个答案:

答案 0 :(得分:19)

使用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);

答案 1 :(得分: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) });

答案 2 :(得分:0)

我现在遇到了同样的问题,我尝试了一些不同的方法。 它不对数组进行排序,而是根据排序列表过滤订单列表,因此它有一些限制,但是对于我的需求它的事件更好,因为它从排序列表中删除了不正确的值:

  • 如果排序列表的值加倍,则只会出现一次 排序清单
  • 如果排序列表中有未包含的项目 order-list,它不会出现在排序列表中

&#13;
&#13;
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/>';
&#13;
&#13;
&#13;

答案 3 :(得分:0)

如果您需要按周期性顺序放置数组的值,则表示:
输入:[1,2,4,4,3,3,2,1]
输出:[1,2,3,4,1,2,3,4]

然后您可以使用以下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;
}