以前作優惠券的時候有用到,並且一直對 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