Skip to content

Commit

Permalink
✨ Add first and last functions
Browse files Browse the repository at this point in the history
  • Loading branch information
TomokiMiyauci committed Apr 16, 2021
1 parent 3da9310 commit 816c978
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/first.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { IsString } from '@/isString'
import { InferArray } from '@/types'

type first<T extends string | unknown[]> = IsString<T> extends true
? string
: T extends never[]
? undefined
: InferArray<T>

/**
* Returns the first element of the given list or string.
*
* @param val - string or any array object
* @returns The first element of the `val`
*
* @example
* String
* first('hello') // 'h'
*
* @example
* Array
* first('hello', 'new', 'world') // 'hello'
* first([]) // undefined
* first(['one', 2, 3, 4]) // 'one'
*/
const first = <T extends string | unknown[]>(val: T): first<T> => {
if (Array.isArray(val)) {
return val.length
? (val.slice(0, 1)[0] as first<T>)
: (undefined as first<T>)
} else {
return (val as string).slice(0, 1) as first<T>
}
}

export { first }
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export { add } from '@/add'
export { divide } from '@/divide'
export { first } from '@/first'
export type { IsBigint } from '@/isBigint'
export { isBigint } from '@/isBigint'
export type { IsNill } from '@/isNill'
Expand All @@ -12,6 +13,7 @@ export type { IsString } from '@/isString'
export { isString } from '@/isString'
export type { IsSymbol } from '@/isSymbol'
export { isSymbol } from '@/isSymbol'
export { last } from '@/last'
export { multiply } from '@/multiply'
export { startsWith } from '@/startsWith'
export { subtract } from '@/subtract'
Expand Down
34 changes: 34 additions & 0 deletions src/last.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { IsString } from '@/isString'
import { InferArray } from '@/types'

type Last<T extends string | unknown[]> = IsString<T> extends true
? string
: T extends never[]
? undefined
: InferArray<T>

/**
* Returns the last element of the given list or string.
*
* @param val - string or any array object
* @returns The last element of the `val`
*
* @example
* String
* last('hello') // 'o'
*
* @example
* Array
* last('hello', 'new', 'world') // 'world'
* last([]) // undefined
* last(['one', 2, 3, 4]) // 4
*/
const last = <T extends string | unknown[]>(val: T): Last<T> => {
if (Array.isArray(val)) {
return val.length ? (val.slice(-1)[0] as Last<T>) : (undefined as Last<T>)
} else {
return (val as string).slice(-1) as Last<T>
}
}

export { last }
34 changes: 34 additions & 0 deletions test/first.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { first } from '@/first'

describe('first', () => {
const table: [string | unknown[], unknown][] = [
['', ''],
['a', 'a'],
[' ab', ' '],
['abcd', 'a'],
['abcde ', 'a'],
['abcd_', 'a'],
[[], undefined],
[[''], ''],
[['hello', 'world'], 'hello'],
[['hello', 'new', 'world'], 'hello'],
[
[['hello', 'new', 'world'], 'test'],
['hello', 'new', 'world']
],
[
[
['hello', 'new', 'world'],
['hello2', 'world']
],
['hello', 'new', 'world']
],
[[0], 0],
[[0, 3, 6, 9], 0],
[[{}], {}]
]

it.each(table)('first(%s) -> %s', (val, expected) => {
expect(first(val)).toEqual(expected)
})
})
31 changes: 31 additions & 0 deletions test/last.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { last } from '@/last'

describe('last', () => {
const table: [string | unknown[], unknown][] = [
['', ''],
['a', 'a'],
[' ab', 'b'],
['abcd', 'd'],
['abcde ', ' '],
['abcd_', '_'],
[[], undefined],
[[''], ''],
[['hello', 'world'], 'world'],
[['hello', 'new', 'world'], 'world'],
[[['hello', 'new', 'world'], 'test'], 'test'],
[
[
['hello', 'new', 'world'],
['hello2', 'world']
],
['hello2', 'world']
],
[[0], 0],
[[0, 3, 6, 9], 9],
[[{}], {}]
]

it.each(table)('last(%s) -> %s', (val, expected) => {
expect(last(val)).toEqual(expected)
})
})

0 comments on commit 816c978

Please sign in to comment.