Skip to content

Commit

Permalink
✨ Add chunk and props functions
Browse files Browse the repository at this point in the history
  • Loading branch information
TomokiMiyauci committed Apr 29, 2021
1 parent 9bafc74 commit bf68be4
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 0 deletions.
43 changes: 43 additions & 0 deletions docs/api/chunk/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->



## chunk variable

> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
>
Return an array of elements split into groups the length of size.

<b>Signature:</b>

```typescript
chunk: <T extends number, U extends unknown[]>(size: T, array: U) => T extends 0 ? U : `${T}` extends `-${number}` ? U : U extends never[] ? U : U extends (infer R)[] ? R[][] : never
```

## Remarks

If array can't be split evenly, the final chunk will be the remaining elements.

## Example 1


```ts
// Basic
chunk(1, ['a', 'b', 'c', 'd']) // [['a'], ['b'], ['c'], ['d']]
chunk(3, ['a', 'b', 'c', 'd']) // [['a', 'b', 'c'], ['d']]
chunk(5, ['a', 'b', 'c', 'd']) // [['a', 'b', 'c', 'd']]

```

## Example 2


```ts
// Illegal size
chunk(0, ['a', 'b', 'c']) // ['a', 'b', 'c']
chunk(-3, ['a', 'b', 'c']) // ['a', 'b', 'c']
chunk(5, []) // []

```

2 changes: 2 additions & 0 deletions docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
| [add](./add/) | Adds first argument and second argument. |
| [and](./and/) | Returns true if both arguments are true; otherwise false. |
| [append](./append/) | Returns a new list containing the contents of the given list, followed by the given value |
| [chunk](./chunk/) | <b><i>(BETA)</i></b> Return an array of elements split into groups the length of size. |
| [dec](./dec/) | Decrements its argument. |
| [defaultTo](./defaultto/) | <b><i>(BETA)</i></b> Returns the second argument if it is not <code>null</code>, <code>undefined</code> or <code>NaN</code>; otherwise the first argument is returned. |
| [divide](./divide/) | Divide its second argument from its first argument. |
Expand Down Expand Up @@ -50,6 +51,7 @@
| [or](./or/) | Returns true if one or both of its arguments are true; otherwise false. |
| [prepend](./prepend/) | Returns a new list with the given value at the front, followed by the contents of the list. |
| [product](./product/) | Multiplies together all the elements of a list. |
| [props](./props/) | <b><i>(BETA)</i></b> Returns a function that when supplied an object returns the indicated property of that object, if it exists. |
| [reverse](./reverse/) | Returns a new list or string with the elements or characters in reverse order. |
| [startsWith](./startswith/) | Checks if a string starts with the provided substring. |
| [subtract](./subtract/) | Subtracts its second argument from its first argument. |
Expand Down
27 changes: 27 additions & 0 deletions docs/api/props/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->



## props variable

> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
>
Returns a function that when supplied an object returns the indicated property of that object, if it exists.

<b>Signature:</b>

```typescript
props: <T extends string | number, U extends Record<PropertyKey, unknown>>(val: T, obj: U) => U extends Record<T, unknown> ? U[T] : undefined
```

## Example


```ts
props('x', { x: 'hello' }) // 'hello'
props(1, { 1: 100 }) // 100
props('x', {}) // undefined

```

2 changes: 2 additions & 0 deletions mod.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { add } from './src/add.ts'
export { and } from './src/and.ts'
export { append } from './src/append.ts'
export { chunk } from './src/chunk.ts'
export { _ } from './src/constants/index.ts'
export { dec } from './src/dec.ts'
export { defaultTo } from './src/defaultTo.ts'
Expand Down Expand Up @@ -41,6 +42,7 @@ export { not } from './src/not.ts'
export { or } from './src/or.ts'
export { prepend } from './src/prepend.ts'
export { product } from './src/product.ts'
export { props } from './src/props.ts'
export { reverse } from './src/reverse.ts'
export { startsWith } from './src/startsWith.ts'
export { subtract } from './src/subtract.ts'
Expand Down
29 changes: 29 additions & 0 deletions src/_/prop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { has } from '../has.ts'

/**
* Returns a function that when supplied an object returns the indicated property of that object, if it exists.
*
* @param val - input property key
* @param obj - The object to query
* @returns The result of safety `obj[val]`
*
* @example
* ```ts
* prop('x', { x: 'hello' }) // 'hello'
* prop(1, { 1: 100 }) // 100
* prop('x', {}) // undefined
* ```
*
* @internal
*/
const prop = <
T extends string | number,
U extends Record<PropertyKey, unknown>
>(
val: T,
obj: U
): U extends Record<T, unknown> ? U[T] : undefined =>
(has(val, obj) ? obj[val] : undefined) as U extends Record<T, unknown>
? U[T]
: undefined
export { prop }
55 changes: 55 additions & 0 deletions src/chunk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { add } from './add.ts'
import { lte } from './lte.ts'

/**
* Return an array of elements split into groups the length of size.
*
* @param size - The length of each chunk
* @param array - The array to process
* @returns - Returns the new array of chunks
*
* @remarks
* If array can't be split evenly, the final chunk will be the remaining elements.
*
* @example
* ```ts
* // Basic
* chunk(1, ['a', 'b', 'c', 'd']) // [['a'], ['b'], ['c'], ['d']]
* chunk(3, ['a', 'b', 'c', 'd']) // [['a', 'b', 'c'], ['d']]
* chunk(5, ['a', 'b', 'c', 'd']) // [['a', 'b', 'c', 'd']]
* ```
*
* @example
* ```ts
* // Illegal size
* chunk(0, ['a', 'b', 'c']) // ['a', 'b', 'c']
* chunk(-3, ['a', 'b', 'c']) // ['a', 'b', 'c']
* chunk(5, []) // []
* ```
*
* @beta
*/
const chunk = <T extends number, U extends unknown[]>(
size: T,
array: U
): T extends 0
? U
: `${T}` extends `-${number}`
? U
: U extends never[]
? U
: U extends (infer R)[]
? R[][]
: never =>
lte(size, 0 as T)
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
(array as any)
: array.reduce(
(acc, _, index) =>
index % size
? acc
: [...(acc as never), array.slice(index, add(index, size))],
[]
)

export { chunk }
26 changes: 26 additions & 0 deletions src/props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { prop } from './_/prop.ts'

/**
* Returns a function that when supplied an object returns the indicated property of that object, if it exists.
*
* @param val - input property key
* @param obj - The object to query
* @returns The result of safety `obj[val]` or `obj[val[0]][val[1]][val[...x]]`
*
* @example
* ```ts
* props('x', { x: 'hello' }) // 'hello'
* props(1, { 1: 100 }) // 100
* props('x', {}) // undefined
* ```
*
* @beta
*/
const props = <
T extends string | number,
U extends Record<PropertyKey, unknown>
>(
val: T,
obj: U
): U extends Record<T, unknown> ? U[T] : undefined => prop(val, obj)
export { props }
21 changes: 21 additions & 0 deletions test/_/prop.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { prop } from '@/_/prop'

describe('prop', () => {
const table: [string | number, Record<PropertyKey, unknown>, unknown][] = [
['', {}, undefined],
['', { ' ': '' }, undefined],
['', { ' ': { '': '' } }, undefined],
[0, {}, undefined],
[0, { 1: '' }, undefined],
[0, { 1: { 0: '' } }, undefined],
['', { '': '' }, ''],
['Hello', { hello: '' }, undefined],
['Hello', { Hello: '' }, ''],
['hello', { hello: '' }, ''],
[0, { 0: 1 }, 1]
]

it.each(table)('prop(%s, %s) -> %s', (a, b, expected) => {
expect(prop(a, b)).toBe(expected)
})
})
51 changes: 51 additions & 0 deletions test/chunk.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { chunk } from '@/chunk'

describe('chunk', () => {
const arr = ['a', 'b', 'c', 'd']
const arr2 = [{}, [], 0, null, undefined]
const table: [number, unknown[], unknown[][] | unknown[]][] = [
[1, [], []],
[0, [], []],
[2, [], []],
[1, [''], [['']]],
[2, [''], [['']]],
[3, [''], [['']]],
[4, [''], [['']]],
[0, [''], ['']],
[-0, [''], ['']],
[-1, [''], ['']],
[-2, [''], ['']],
[-3, [''], ['']],
[-4, [''], ['']],
[1, arr, [['a'], ['b'], ['c'], ['d']]],
[
2,
arr,
[
['a', 'b'],
['c', 'd']
]
],
[3, arr, [['a', 'b', 'c'], ['d']]],
[4, arr, [['a', 'b', 'c', 'd']]],
[5, arr, [['a', 'b', 'c', 'd']]],
[6, arr, [['a', 'b', 'c', 'd']]],
[1, arr2, [[{}], [[]], [0], [null], [undefined]]],
[2, arr2, [[{}, []], [0, null], [undefined]]],
[
3,
arr2,
[
[{}, [], 0],
[null, undefined]
]
],
[4, arr2, [[{}, [], 0, null], [undefined]]],
[5, arr2, [[{}, [], 0, null, undefined]]],
[6, arr2, [[{}, [], 0, null, undefined]]]
]

it.each(table)('chunk(%d, %s) -> %s', (a, b, expected) => {
expect(chunk(a, b)).toEqual(expected)
})
})
21 changes: 21 additions & 0 deletions test/props.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { props } from '@/props'

describe('props', () => {
const table: [string | number, Record<PropertyKey, unknown>, unknown][] = [
['', {}, undefined],
['', { ' ': '' }, undefined],
['', { ' ': { '': '' } }, undefined],
[0, {}, undefined],
[0, { 1: '' }, undefined],
[0, { 1: { 0: '' } }, undefined],
['', { '': '' }, ''],
['Hello', { hello: '' }, undefined],
['Hello', { Hello: '' }, ''],
['hello', { hello: '' }, ''],
[0, { 0: 1 }, 1]
]

it.each(table)('props(%s, %s) -> %s', (a, b, expected) => {
expect(props(a, b)).toBe(expected)
})
})

0 comments on commit bf68be4

Please sign in to comment.