對一個對象數組進行多維排序

以前作優惠券的時候有用到,並且一直對 sort 的順序似是而非,因此作一個總結。javascript

對如下數組進行排序,要求:價格低排前面、同價格郵費低在前、前兩個相等銷量高的在前。前端

const arr = [
  { name: '商品01', price: 123.0, sales: 123, postage: 19 },
  { name: '商品02', price: 124.0, sales: 123, postage: 0 },
  { name: '商品03', price: 123.0, sales: 133, postage: 29 },
  { name: '商品04', price: 125.0, sales: 123, postage: 9 },
  { name: '商品05', price: 123.0, sales: 143, postage: 19 }
];
複製代碼

對 sort 函數簡單記憶:返回結果大於 0,交換位置,不然不變。java

利用 js 中 0 爲 false 的特性,短路寫法能夠一行搞定:後端

arr.sort((a, b) => {
  return a.price - b.price || a.postage - b.postage || b.sales - a.sales;
});
// arr:
[
{"name":"商品05","price":123,"sales":143,"postage":19},
{"name":"商品01","price":123,"sales":123,"postage":19},
{"name":"商品03","price":123,"sales":133,"postage":29},
{"name":"商品02","price":124,"sales":123,"postage":0},
{"name":"商品04","price":125,"sales":123,"postage":9}
]
複製代碼

雖然這也不麻煩,可是能不能更方便一點?數組

實現一個對象數組多維排序函數:函數

const keys = ['price', 'postage', 'sales']; // 傳入要排序的 key,優先級從高到低
const orders = [1, 1, -1]; // 每一個 key 的排序方式,1 正序,-1 倒序

function multiSort(array, keys, orders) {
  if (!keys) return array;
  if (!orders) {
    orders = Array.from({ length: keys.length }, () => 1); // 默認從小到大排序
  }
  
  return [...array].sort((a, b) => {
    for (let [index, key] of keys.entries()) {
      if (a[key] - b[key] === 0) continue; // 若是當前維度條件相等,判斷下一個維度
      return (a[key] - b[key]) * orders[index];
    }
    return 0; // 所有相等返回 0
  });
}

const arr1 = multiSort(arr, keys, orders)
// arr1:
[
{"name":"商品05","price":123,"sales":143,"postage":19},
{"name":"商品01","price":123,"sales":123,"postage":19},
{"name":"商品03","price":123,"sales":133,"postage":29},
{"name":"商品02","price":124,"sales":123,"postage":0},
{"name":"商品04","price":125,"sales":123,"postage":9}
]
複製代碼

其實前端能用到排序的機會並很少,通常列表都有分頁,排序都是把條件傳到後端。可是對於優惠券,或者其餘數量一次性返回的列表進行排序,就須要本身上場了。post

固然,這個函數是不嚴謹的:數組是淺拷貝,沒有 keys 和 orders 長度不一致的防呆功能,沒有參數類型驗證。大型項目中這些都是要考慮的問題。ui

相關文章
相關標籤/搜索