【问题标题】:Sort an array in the same order of another array以与另一个数组相同的顺序对数组进行排序
【发布时间】:2015-02-07 01:25:14
【问题描述】:

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

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

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

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

它没有逻辑顺序,它们只是按照这个顺序。对我来说有意义的是将每个数组与正确排序的数组进行比较。我想我看到有人用 PHP 做这个,但我找不到 JavaScript 解决方案。有谁知道如何做到这一点?我已经尝试了几个小时,但我被难住了。

【问题讨论】:

  • 您希望它们按此顺序排列是否有特定原因?如果您只希望它们以 same 顺序排列,则可以在两个数组上使用 .sort()

标签: javascript sorting compare


【解决方案1】:

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

【讨论】:

  • 这有效并回答了我提出的问题。我问了这个问题,但没有说我的原始数组实际上是一个对象。为了解决这个问题,我能够使用_.keys 从对象中获取密钥,然后我能够使用您的方法reference_array.indexOf(a) - reference_array.indexOf(b); 对它们进行排序我用我的确切代码(stackoverflow.com/questions/28395477/…)问了第二个问题,但是在最后我必须弄清楚对象到数组的转换。我用这个答案和那边的答案最终解决了我的排序问题。
  • 如果您对使用该库的解决方案感兴趣,请记得用underscorejs 标记您的问题。
【解决方案2】:

您可以通过模式工厂功能实现一些分拣机。然后使用您的模式创建排序器并将其应用于您的数组:

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) });

【讨论】:

    【解决方案3】:

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

    • 如果排序列表的值加倍,它只会出现一次 排序列表
    • 如果排序列表中的项目不包含在 order-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/>';

    【讨论】:

      【解决方案4】:

      如果您需要按循环顺序放置数组的值,则意味着:
      输入:[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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-05
        相关资源
        最近更新 更多