Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 11x 14x 14x 14x 14x 212x 212x 70x 70x 70x 70x 142x 14x 14x 106x 106x 106x 14x | import { OneOrMore } from '../types'
export type OrderByRulesRuleObject<T> = {
/**
* 迭代函数。
*
* @param item 项目
* @returns 返回参与排序计算的值
*/
iteratee: (item: T) => any
/**
* 类型。
*/
type: 'asc' | 'desc'
}
export type OrderByRulesRuleArray<T> = [
/**
* 迭代函数。
*
* @param item 项目
* @returns 返回参与排序计算的值
*/
iteratee: (item: T) => any,
/**
* 类型。
*/
type: 'asc' | 'desc',
]
export type OrderByRulesRule<T> =
| OrderByRulesRuleObject<T>
| OrderByRulesRuleArray<T>
/**
* 允许指定一个或多个规则对数据进行排序。
*
* @param data 要排序的数据
* @param rules 一个或多个规则
* @returns 返回排序后的数据
* @example
* ```ts
* orderByRules(
* ['x', 'xyz', 'xy'],
* {
* iteratee: item => item.length,
* type: 'desc',
* },
* )
* // => ['xyz', 'xy', 'x']
* ```
*/
export function orderByRules<T>(
data: T[],
rules: OneOrMore<OrderByRulesRule<T>>,
): T[] {
return (
(Array.isArray(rules)
? typeof rules[0] === 'function'
? [rules]
: rules
: [rules]) as OrderByRulesRule<T>[]
)
.map<OrderByRulesRuleObject<T>>(rule =>
Array.isArray(rule)
? {
iteratee: rule[0],
type: rule[1],
}
: rule,
)
.reduce<T[]>((orderedData, rule) => {
const cachedKeys: T[] = []
const cachedValues: any[] = []
const cachedIteratee: OrderByRulesRuleObject<T>['iteratee'] = item => {
const index = cachedKeys.indexOf(item)
if (index === -1) {
const value = rule.iteratee(item)
cachedKeys.push(item)
cachedValues.push(value)
return value
}
return cachedValues[index]
}
const isAsc = rule.type === 'asc'
orderedData.sort((a, b) => {
a = cachedIteratee(a)
b = cachedIteratee(b)
return a === b ? 0 : a > b ? (isAsc ? 1 : -1) : isAsc ? -1 : 1
})
return orderedData
}, data.slice())
}
|