Skip to content

Commit

Permalink
feat(array): range
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Apr 28, 2021
1 parent c8f1bb5 commit 657d135
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 5 deletions.
9 changes: 8 additions & 1 deletion src/array.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { flattenArrayable } from './array'
import { flattenArrayable, range } from './array'

it('flattenArrayable', () => {
expect(flattenArrayable()).toEqual([])
Expand All @@ -8,3 +8,10 @@ it('flattenArrayable', () => {
expect(flattenArrayable([1, [1, 2]])).toEqual([1, 1, 2])
expect(flattenArrayable([1, [1, [2]]])).toEqual([1, 1, [2]])
})

it('range', () => {
expect(range(0)).toEqual([])
expect(range(2)).toEqual([0, 1])
expect(range(2, 5)).toEqual([2, 3, 4])
expect(range(2, 10, 2)).toEqual([2, 4, 6, 8])
})
64 changes: 60 additions & 4 deletions src/array.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Arrayable, Nullable } from './types'

/**
* Convert Arrayable<T> to Array<T>
* Convert `Arrayable<T>` to `Array<T>`
*
* @category Array
*/
export function toArray<T>(array?: Nullable<Arrayable<T>>): Array<T> {
array = array || []
Expand All @@ -11,14 +13,18 @@ export function toArray<T>(array?: Nullable<Arrayable<T>>): Array<T> {
}

/**
* Convert Arrayable<T> to Array<T>
* Convert `Arrayable<T>` to `Array<T>` and flat it
*
* @category Array
*/
export function flattenArrayable<T>(array?: Nullable<Arrayable<T | Array<T>>>): Array<T> {
return toArray(array).flat(1) as Array<T>
}

/**
* Use rest arguments to merge arrays
*
* @category Array
*/
export function mergeArrayable<T>(...args: Nullable<Arrayable<T>>[]): Array<T> {
return args.flatMap(i => toArray(i))
Expand All @@ -27,6 +33,7 @@ export function mergeArrayable<T>(...args: Nullable<Arrayable<T>>[]): Array<T> {
/**
* Divide an array into two parts by a filter function.
*
* @category Array
* @example const [odd, even] = partition([1, 2, 3, 4], i => i % 2 != 0)
*/
export function partition<T>(array: readonly T[], filter: (i: T, idx: number, arr: readonly T[]) => any) {
Expand All @@ -36,17 +43,34 @@ export function partition<T>(array: readonly T[], filter: (i: T, idx: number, ar
return [pass, fail]
}

/**
* Unique an Array
*
* @category Array
*/
export function uniq<T>(array: readonly T[]): T[] {
return Array.from(new Set(array))
}

/**
* Get last item
*
* @category Array
*/
export function last(array: readonly []): undefined
export function last<T>(array: readonly T[]): T
export function last<T>(array: readonly T[]): T | undefined {
return at(array, -1)
}

/**
* Remove an item from Array
*
* @category Array
*/
export function remove<T>(array: T[], value: T) {
if (!array)
return false
const index = array.indexOf(value)
if (index >= 0) {
array.splice(index, 1)
Expand All @@ -55,17 +79,49 @@ export function remove<T>(array: T[], value: T) {
return false
}

/**
* Get nth item of Array. Negative for backward
*
* @category Array
*/
export function at(array: readonly [], index: number): undefined
export function at<T>(array: readonly T[], index: number): T
export function at<T>(array: readonly T[] | [], index: number): T | undefined {
const len = array.length
if (!len)
return undefined

index = index % len

if (index < 0)
index += len

return array[index]
}

/**
* Genrate a range array of numbers. The `stop` is exclusive.
*
* @category Array
*/
export function range(stop: number): number[]
export function range(start: number, stop: number, step?: number): number[]
export function range(...args: any): number[] {
let start: number, stop: number, step: number

if (args.length === 1) {
start = 0
step = 1;
([stop] = args)
}
else {
([start, stop, step = 1] = args)
}

const arr: number[] = []
let current = start
while (current < stop) {
arr.push(current)
current += step || 1
}

return arr
}

0 comments on commit 657d135

Please sign in to comment.