如何避免必须对具有 2 个条件的 javascript 数组进行两次排序

How to avoid having to do sorting two times a javascript array with 2 conditions

我有一个订单数组,我需要根据 delivery_time 属性对其进行排序,以便可以先处理最早的订单。但我们也可以选择立即交付订单。因此,无论交货时间如何,立即 delivery_method 订单都需要位于数组的开头。

现在我通过使用 2 个排序函数来实现这一点,第一个根据 delivery_time 属性对订单进行排序,第二个根据 delivery_method_id 属性对数组进行排序(delivery_method_id == 1 表示立即交付)。我怎样才能只使用一个 sort 函数获得相同的结果?

orders.sort((a, b) => {
  return a.delivery_time - b.delivery_time; //sort based on delivery_time
}).sort((a, b) => {
  return a.delivery_method_id === 1 ? -1: 0; //sort based on delivery_method_id 
});

我尝试在第一个排序函数本身中保留这两个条件,但在那种情况下,我在每一天的开始位置而不是第一个位置得到立即交货订单(我希望我清楚地解释了这种情况)

如何避免使用两个函数对订单数组进行排序?我已经安装了 underscore.js 如果它也可以使用的话。

示例数据(订单)

[{
  "id": 149677,
  "delivery_time": "2020-02-20 19:00:00",
  "delivery_method_id": 2
}, {
  "id": 149737,
  "delivery_time": "2020-02-20 21:00:00",
  "delivery_method_id": 2
}, {
  "id": 160919,
  "delivery_time": "2020-03-12 13:00:00",
  "delivery_method_id": 3
},
{
  "id": 160920,
  "delivery_time": "2020-03-12 13:00:00",  // according to delivery time, this should be at the bottom, but because the delivery_method_id == 1 , I need to push this to the top/beginning of array, this is why I had to use 2 sorts
  "delivery_method_id": 1
}] 

因此,假设您还希望 2 和 3 位于其后,那么我们将检查 id 是否相等,如果相等,我们按日期排序,如果不相等,我们按 id 排序。

var data = [{
    "id": 149677,
    "delivery_time": "2020-02-20 19:00:00",
    "delivery_method_id": 2
  }, {
    "id": 149737,
    "delivery_time": "2020-02-20 21:00:00",
    "delivery_method_id": 2
  }, {
    "id": 160919,
    "delivery_time": "2020-03-12 13:00:00",
    "delivery_method_id": 3
  },
  {
    "id": 160920,
    "delivery_time": "2020-03-12 13:00:00",
    "delivery_method_id": 1
  }
]

var updated = data.sort((a,b) => {
  var sortProp = a.delivery_method_id === b.delivery_method_id ? 'delivery_time' : 'delivery_method_id'
  return a[sortProp] > b[sortProp] ? 1 : -1
})

console.log(updated)

const orders = [{
  "id": 149677,
  "delivery_time": "2020-02-20 19:00:00",
  "delivery_method_id": 2
}, {
  "id": 149737,
  "delivery_time": "2020-02-20 21:00:00",
  "delivery_method_id": 2
}, {
  "id": 160919,
  "delivery_time": "2020-03-12 13:00:00",
  "delivery_method_id": 3
},
{
  "id": 160920,
  "delivery_time": "2020-03-12 13:00:00",  // according to delivery time, this should be at the bottom, but because the delivery_method_id == 1 , I need to push this to the top/beginning of array, this is why I had to use 2 sorts
  "delivery_method_id": 1
}] 

orders.sort((a,b) => {
  if((a.delivery_method_id === 1 && b.delivery_method_id === 1) || (a.delivery_method_id !== 1 && b.delivery_method_id !== 1)){
    return a.delivery_time - b.delivery_time
  }
  return a.delivery_method_id === 1 ? -1 : 1
})

console.log(orders)

这总是首先对 delivery_method_id 为 1 的对象进行排序,但如果两个对象都是如此,则 delivery_time 仍用于在它们之间进行排序。当两个对象的 delivery_method_id 都不为 1 时,只有 delivery_time 用于排序。

console.log([
  {id: 1, delivery_method_id: 2, delivery_time: 1},
  {id: 2, delivery_method_id: 1, delivery_time: 2},
  {id: 3, delivery_method_id: 1, delivery_time: 2},
  {id: 4, delivery_method_id: 1, delivery_time: 1},
  {id: 5, delivery_method_id: 1, delivery_time: 2},
  {id: 6, delivery_method_id: 3, delivery_time: 7},
  {id: 7, delivery_method_id: 3, delivery_time: 8},
  {id: 8, delivery_method_id: 3, delivery_time: 6},
  {id: 9, delivery_method_id: 2, delivery_time: 6}
].sort((a, b)=>{
  return a.delivery_method_id === 1 ?
    (b.delivery_method_id === 1 ? a.delivery_time - b.delivery_time : -1) :
    (b.delivery_method_id === 1 ? 1 : a.delivery_time - b.delivery_time)
}))