Skip to content

Commit

Permalink
feat(orderByRules): OrderByRulesRuleArray
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Oct 7, 2024
1 parent c7ab55b commit 8efb614
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 22 deletions.
30 changes: 30 additions & 0 deletions src/utils/orderByRules.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,34 @@ describe('orderByRules', () => {
{ a: 'x', b: 1 },
])
})

test('数组规则正常', () => {
expect(orderByRules(strData, [item => item.length, 'desc'])).toEqual([
'hello',
'花间一壶酒',
'fjc',
'20',
'=',
])

expect(orderByRules(numData, [item => item, 'asc'])).toEqual([
-5, 0, 1.2, 4, 20,
])

expect(
orderByRules(arrData, [
{
iteratee: item => item.b,
type: 'desc',
},
[item => item.a.charCodeAt(0), 'asc'],
]),
).toEqual([
{ a: 'x', b: 3 },
{ a: 'x', b: 1 },
{ a: 'y', b: 4 },
{ a: 'y', b: 2 },
{ a: 'z', b: 1 },
])
})
})
76 changes: 54 additions & 22 deletions src/utils/orderByRules.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { castArray } from 'lodash-uni'
import { OneOrMore } from '../types'

export type OrderByRulesRule<T> = {
export type OrderByRulesRuleObject<T> = {
/**
* 迭代函数。
*
Expand All @@ -15,6 +14,24 @@ export type OrderByRulesRule<T> = {
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>

/**
* 允许指定一个或多个规则对数据进行排序。
*
Expand All @@ -37,28 +54,43 @@ export function orderByRules<T>(
data: T[],
rules: OneOrMore<OrderByRulesRule<T>>,
): T[] {
return castArray(rules).reduce<T[]>((orderedData, rule) => {
const cachedKeys: T[] = []
const cachedValues: any[] = []
const cachedIteratee: OrderByRulesRule<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 (
(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]
}
return cachedValues[index]
}

const isAsc = rule.type === 'asc'
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
})
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())
return orderedData
}, data.slice())
}

0 comments on commit 8efb614

Please sign in to comment.