[Perf] Optimize iteratees.orderBy
This commit is contained in:
parent
412f26a6bf
commit
5563b0b4f4
@ -1,6 +1,8 @@
|
|||||||
type CollectionByKey<Member> = Record<number | string, Member>;
|
type CollectionByKey<Member> = Record<number | string, Member>;
|
||||||
|
|
||||||
type OrderDirection = 'asc' | 'desc';
|
type OrderDirection =
|
||||||
|
'asc'
|
||||||
|
| 'desc';
|
||||||
|
|
||||||
interface OrderCallback<T> {
|
interface OrderCallback<T> {
|
||||||
(member: T): any;
|
(member: T): any;
|
||||||
@ -51,55 +53,30 @@ export function omit<T, K extends keyof T>(object: T, keys: K[]) {
|
|||||||
|
|
||||||
export function orderBy<T>(
|
export function orderBy<T>(
|
||||||
collection: T[],
|
collection: T[],
|
||||||
orderKey: (keyof T) | OrderCallback<T> | ((keyof T) | OrderCallback<T>)[],
|
orderRule: (keyof T) | OrderCallback<T> | ((keyof T) | OrderCallback<T>)[],
|
||||||
mode: OrderDirection | [OrderDirection, OrderDirection] = 'asc',
|
mode: OrderDirection | [OrderDirection, OrderDirection] = 'asc',
|
||||||
): T[] {
|
): T[] {
|
||||||
|
function compareValues(a: T, b: T, currentOrderRule: (keyof T) | OrderCallback<T>, isAsc: boolean) {
|
||||||
|
const aValue = (typeof currentOrderRule === 'function' ? currentOrderRule(a) : a[currentOrderRule]) || 0;
|
||||||
|
const bValue = (typeof currentOrderRule === 'function' ? currentOrderRule(b) : b[currentOrderRule]) || 0;
|
||||||
|
|
||||||
|
return isAsc ? aValue - bValue : bValue - aValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(orderRule)) {
|
||||||
|
const [mode1, mode2] = Array.isArray(mode) ? mode : [mode, mode];
|
||||||
|
const [orderRule1, orderRule2] = orderRule;
|
||||||
|
const isAsc1 = mode1 === 'asc';
|
||||||
|
const isAsc2 = mode2 === 'asc';
|
||||||
|
|
||||||
|
return collection.sort((a, b) => {
|
||||||
|
return compareValues(a, b, orderRule1, isAsc1) || compareValues(a, b, orderRule2, isAsc2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const isAsc = mode === 'asc';
|
||||||
return collection.sort((a, b) => {
|
return collection.sort((a, b) => {
|
||||||
if (Array.isArray(orderKey)) {
|
return compareValues(a, b, orderRule, isAsc);
|
||||||
const [mode1, mode2] = Array.isArray(mode) ? mode : [mode, mode];
|
|
||||||
const [orderKey1, orderKey2] = orderKey;
|
|
||||||
|
|
||||||
let aValue1;
|
|
||||||
let bValue1;
|
|
||||||
|
|
||||||
if (typeof orderKey1 === 'function') {
|
|
||||||
aValue1 = orderKey1(a) || 0;
|
|
||||||
bValue1 = orderKey1(b) || 0;
|
|
||||||
} else if (typeof orderKey1 === 'string') {
|
|
||||||
aValue1 = a[orderKey1] || 0;
|
|
||||||
bValue1 = b[orderKey1] || 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aValue1 !== bValue1) {
|
|
||||||
return mode1 === 'asc' ? aValue1 - bValue1 : bValue1 - aValue1;
|
|
||||||
} else {
|
|
||||||
let aValue2;
|
|
||||||
let bValue2;
|
|
||||||
|
|
||||||
if (typeof orderKey2 === 'function') {
|
|
||||||
aValue2 = orderKey2(a) || 0;
|
|
||||||
bValue2 = orderKey2(b) || 0;
|
|
||||||
} else if (typeof orderKey2 === 'string') {
|
|
||||||
aValue2 = a[orderKey2] || 0;
|
|
||||||
bValue2 = b[orderKey2] || 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mode2 === 'asc' ? aValue2 - bValue2 : bValue2 - aValue2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let aValue;
|
|
||||||
let bValue;
|
|
||||||
|
|
||||||
if (typeof orderKey === 'function') {
|
|
||||||
aValue = orderKey(a) || 0;
|
|
||||||
bValue = orderKey(b) || 0;
|
|
||||||
} else if (typeof orderKey === 'string') {
|
|
||||||
aValue = a[orderKey] || 0;
|
|
||||||
bValue = b[orderKey] || 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mode === 'asc' ? aValue - bValue : bValue - aValue;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user