背景
在開發(fā)過程中腹泌,對象數(shù)組的排序會經(jīng)常用到嘶卧。如果想要實現(xiàn)多個字段按優(yōu)先級排序的話,如何處理真屯?這種情況比較少見。舉例來說穷娱,有以下對象數(shù)組:
const list = [
{
"title": "This is a deme page",
"name": "Aborn Jiang",
"age": 21
},
{
"title": "mindpress is a good framework",
"name": "John",
"age": 31
},
{
"title": "Goodness",
"name": "Aborn Jiang",
"age": 19
}
]
如果我們想按 name
字段排序绑蔫,當name
字段相同時,再按title
字段排序泵额。
放得更加寬泛點配深,可以按任意多字段排序。
單字段排序
如果只按name
排序嫁盲,那調(diào)用sort
方法如下:
const sortedList = list.sort((a, b) =>
a.name.localeCompare(b.name)
)
兩字段排序
如果先按name
排序篓叶,在name
相同的情況下,再按 age
排序羞秤,寫法臺下:
const sortedList = list.sort((a, b) =>
a.name.localeCompare(b.name) || a.age - b.age
)
通用多字段排序
由兩字段再擴展到任意字段缸托,其實是我們需要分別判斷每個字段,當前一個字段比較后不為 0瘾蛋,則返回俐镐;如果為 0表示繼續(xù)采用后一個字段進行排序,通用寫法如下:
export interface SortFields {
[field: string]: -1 | 1
}
export type SortOptions = SortFields
export const get = (obj: any, path: string): any => path.split('.').reduce((acc, part) => acc && acc[part], obj)
/**
* Sort list of items by givin options
* sort array of object by multi fields.
* example:
* const sortedArray = sortList(toBeSortedArray, { 'createTime': -1, 'title': 1 })
*/
export const sortList = (data: any[], params: SortOptions) => {
const comperable = new Intl.Collator(params.$locale as string, {
numeric: params.$numeric as boolean,
caseFirst: params.$caseFirst as any,
sensitivity: params.$sensitivity as any
})
const keys = Object.keys(params)
data = data.sort((a, b) => {
let res = 0;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const values = [get(a, key), get(b, key)]
.map((value) => {
// `null` values are treated as `"null"` strings and ordered alphabetically
// Turn `null` values into `undefined` so they place at the end of the list
if (value === null) {
return undefined
}
// Convert Date object to ISO string
if (value instanceof Date) {
return value.toISOString()
}
return value
})
if (params[key as keyof SortOptions] === -1) {
values.reverse()
}
res = comperable.compare(values[0], values[1])
if (res != 0) return res;
}
return res;
})
return data
}
調(diào)用舉例:
sortedArray = sortList(toBeSortedArray, { 'createTime': -1, 'title': 1 })
先按 createTime
從最新到最舊排序(逆序哺哼,所以用-1
)佩抹,在時間相同的情況下,使用title
排序(正序取董,用1
)
代碼見: https://github.com/aborn/mindpress/blob/main/mindpress-fe/server/utils/query/sort.ts