Skip to content

Commit

Permalink
feat: new function - sort
Browse files Browse the repository at this point in the history
  • Loading branch information
GreatAuk committed May 10, 2024
1 parent e7a5548 commit c3443d5
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 7 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ pnpm add @utopia-utils/dom
* [awaitTo](https://github.com/scopsy/await-to-js): Async await wrapper for easy error handling without try-catch。[source](https://github.com/GreatAuk/utopia-utils/blob/main/packages/core/src/awaitTo.ts)
* escapeStringRegexp: 把字符串中的特殊字符转义为它可以在正则表达式中使用的形式。[source](https://github.com/GreatAuk/utopia-utils/blob/main/packages/core/src/escapeStringRegexp.ts)
* toFixedWithoutZeros: `Number.toFixed` 并移除末尾的零。[source](https://github.com/GreatAuk/utopia-utils/blob/main/packages/core/src/math.ts)
* average: 计算数组的平均值。[source](https://github.com/GreatAuk/utopia-utils/blob/main/packages/core/src/math.ts)
* average: 计算数组的平均值,支持 `object`[source](https://github.com/GreatAuk/utopia-utils/blob/main/packages/core/src/math.ts)
* sum: 计算数组的和,支持 `object`[source](https://github.com/GreatAuk/utopia-utils/blob/main/packages/core/src/math.ts)
* sort: 数组排序,支持 `object`[source](https://github.com/GreatAuk/utopia-utils/blob/main/packages/core/src/sort.ts)
* [debounce](https://github.com/niksy/throttle-debounce#debounce): 防抖。(export from [throttle-debounce](https://github.com/niksy/throttle-debounce)
* [throttle](https://github.com/niksy/throttle-debounce#throttle): 节流。(export from [throttle-debounce](https://github.com/niksy/throttle-debounce)
* callLimit: 限制函数调用次数。[source](https://github.com/GreatAuk/utopia-utils/blob/main/packages/core/src/callLimit.ts)
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export * from './randomInt'
export * from './randomString'
export * from './retry'
export * from './sleep'
export * from './sort'
export * from './union'
export * from './unique'
export * from './uniqueWith'
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ export function toFixedWithoutZeros(num: number, precision: number): string {
export function average<T extends number>(arr: readonly T[]): number
export function average<T extends object>(
arr: readonly T[],
fn: (item: T) => number
getter: (item: T) => number
): number
export function average<T extends object | number>(
arr: readonly any[],
fn?: (item: T) => number,
getter?: (item: T) => number,
): number {
return arr.reduce((acc, item) => acc + (fn ? fn(item) : item), 0) / arr.length
return arr.reduce((acc, item) => acc + (getter ? getter(item) : item), 0) / arr.length
}

/**
Expand All @@ -50,8 +50,8 @@ export function average<T extends object | number>(
export function sum<T extends number>(arr: readonly T[]): number
export function sum<T extends object>(
arr: readonly T[],
fn: (item: T) => number
getter: (item: T) => number
): number
export function sum<T extends object | number>(arr: readonly any[], fn?: (item: T) => number): number {
return (arr || []).reduce((acc, item) => acc + (fn ? fn(item) : item), 0)
export function sum<T extends object | number>(arr: readonly any[], getter?: (item: T) => number): number {
return (arr || []).reduce((acc, item) => acc + (getter ? getter(item) : item), 0)
}
26 changes: 26 additions & 0 deletions packages/core/src/sort.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { describe, expect, it } from 'vitest'

import { sort } from './sort'

describe('sort', () => {
it('sorts numbers in ascending order', () => {
expect(sort([3, 1, 2])).toEqual([1, 2, 3])
})
it('sorts numbers in descending order', () => {
expect(sort([3, 1, 2], { desc: true })).toEqual([3, 2, 1])
})
it('sorts objects in ascending order', () => {
const arr = [{ value: 3 }, { value: 1 }, { value: 2 }]
expect(sort(arr, { getter: item => item.value })).toEqual([{ value: 1 }, { value: 2 }, { value: 3 }])
})
it('sorts objects in descending order', () => {
const arr = [{ value: 3 }, { value: 1 }, { value: 2 }]
expect(sort(arr, { getter: item => item.value, desc: true })).toEqual([{ value: 3 }, { value: 2 }, { value: 1 }])
})
it('return a new array', () => {
const arr = [3, 1, 2]
const sorted = sort(arr)
expect(sorted).toEqual([1, 2, 3])
expect(sorted).not.toBe(arr)
})
})
38 changes: 38 additions & 0 deletions packages/core/src/sort.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
interface SortOptions<T> {
getter?: (item: T) => number
desc?: boolean
}

/**
* Sorts an array of objects or numbers based on a specified getter function.
*
* @template T - The type of the array elements.
* @param {readonly T[]} arr - The array to be sorted.
* @param {SortOptions<T>} [options={}] - The sorting options.
* @param {Function} [options.getter] - The getter function to extract the value to be used for sorting.
* @param {boolean} [options.desc=false] - Specifies whether to sort in descending order.
* @returns {T[]} - The sorted array.
* @example
* ```ts
* sort([3, 1, 2]) // [1, 2, 3]
* sort([3, 1, 2], { desc: true }) // [3, 2, 1]
* sort([{ value: 3 }, { value: 1 }, { value: 2 }], { getter: item => item.value }) // [{ value: 1 }, { value: 2 }, { value: 3 }]
* ```
*/
export function sort<T extends number>(arr: readonly T[], options?: SortOptions<T>): T[]
export function sort<T extends object>(
arr: readonly T[],
options: SortOptions<T>
): T[]
export function sort<T extends object | number>(
arr: readonly T[],
options: SortOptions<T> = {},
): T[] {
const { getter, desc = false } = options

const getter_ = (item: T) => getter ? getter(item) : item as number
const asc = (a: T, b: T) => getter_(a) - getter_(b)
const dsc = (a: T, b: T) => getter_(b) - getter_(a)

return arr.slice().sort(desc ? dsc : asc)
}

0 comments on commit c3443d5

Please sign in to comment.