mirror of
https://github.com/toss/es-toolkit.git
synced 2024-11-24 03:32:58 +03:00
fix(ary, unary): Fix guard in ary & unary, add Korean docs
This commit is contained in:
parent
d7d3cd28a2
commit
b2427e1f4b
@ -131,6 +131,8 @@ function sidebar(): DefaultTheme.Sidebar {
|
||||
{ text: 'negate', link: '/ko/reference/function/negate' },
|
||||
{ text: 'once', link: '/ko/reference/function/once' },
|
||||
{ text: 'noop', link: '/ko/reference/function/noop' },
|
||||
{ text: 'ary', link: '/reference/function/ary' },
|
||||
{ text: 'unary', link: '/reference/function/unary' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
37
docs/ko/reference/function/ary.md
Normal file
37
docs/ko/reference/function/ary.md
Normal file
@ -0,0 +1,37 @@
|
||||
# ary
|
||||
|
||||
인자를 최대 `n`개까지만 제한해서 받는 새로운 함수를 만들어요. 그 이상으로 주어진 인자는 무시해요.
|
||||
|
||||
## 인터페이스
|
||||
|
||||
```typescript
|
||||
function ary<F extends (...args: any[]) => any>(
|
||||
func: F,
|
||||
n: number
|
||||
): (...args: any[]) => ReturnType<F>;
|
||||
```
|
||||
|
||||
### 파라미터
|
||||
|
||||
- `func` (`F`): 인자를 받는 것을 제한할 함수.
|
||||
- `n` (`number`, 선택): 최대로 받을 인자의 숫자.
|
||||
|
||||
### 반환 값
|
||||
|
||||
(`(...args: any[]) => ReturnType<F>`): 받을 수 있는 인자의 숫자가 제한된 함수.
|
||||
|
||||
## 예시
|
||||
|
||||
```typescript
|
||||
import { ary } from 'es-toolkit/function';
|
||||
|
||||
function fn(a, b, c) {
|
||||
console.log(arguments);
|
||||
}
|
||||
|
||||
ary(fn, 2)(1, 2, 3); // [Arguments] { '0': 1, '1': 2 }
|
||||
ary(fn); // [Arguments] { '0': 1, '1': 2, '2': 3 }
|
||||
ary(fn, -1); // [Arguments] {}
|
||||
ary(fn, 1.5); // [Arguments] { '0': 1 }
|
||||
ary(fn, 2, {}); // [Arguments] { '0': 1, '1': 2, '2': 3 }
|
||||
```
|
29
docs/ko/reference/function/unary.md
Normal file
29
docs/ko/reference/function/unary.md
Normal file
@ -0,0 +1,29 @@
|
||||
# unary
|
||||
|
||||
인자를 최대 1개만 받는 새로운 함수를 만들어요. 그 이상으로 주어진 인자는 무시해요.
|
||||
|
||||
## 인터페이스
|
||||
|
||||
```typescript
|
||||
function unary<F extends (...args: any[]) => any>(func: F): (...args: any[]) => ReturnType<F>;
|
||||
```
|
||||
|
||||
### 파라미터
|
||||
|
||||
- `func` (`F`): 인자를 1개만 받도록 할 함수
|
||||
|
||||
### 반환 값
|
||||
|
||||
(`(...args: any[]) => ReturnType<F>`): 인자를 최대 1개만 받도록 한 함수
|
||||
|
||||
## 예시
|
||||
|
||||
```typescript
|
||||
import { unary } from 'es-toolkit/function';
|
||||
|
||||
function fn(a, b, c) {
|
||||
console.log(arguments);
|
||||
}
|
||||
|
||||
unary(fn)(1, 2, 3); // [Arguments] { '0': 1 }
|
||||
```
|
@ -7,8 +7,7 @@ Creates a function that invokes func, with up to n arguments, ignoring any addit
|
||||
```typescript
|
||||
function ary<F extends (...args: any[]) => any>(
|
||||
func: F,
|
||||
n: number = func.length,
|
||||
guard?: any
|
||||
n: number
|
||||
): (...args: any[]) => ReturnType<F>;
|
||||
```
|
||||
|
||||
@ -16,7 +15,6 @@ function ary<F extends (...args: any[]) => any>(
|
||||
|
||||
- `func` (`F`): The function to cap arguments for.
|
||||
- `n` (`number`, optional): The arity cap, defaulting to the number of parameters of `func`. Negative numbers will be treated as `0`, and decimals will be rounded down.
|
||||
- `guard` (`any`, optional): Enables use as an iteratee for methods like `map`.
|
||||
|
||||
### Returns
|
||||
|
||||
|
73
src/compat/function/ary.spec.ts
Normal file
73
src/compat/function/ary.spec.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { ary } from './ary';
|
||||
|
||||
describe('ary', () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function fn(_a: unknown, _b: unknown, _c: unknown) {
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
return Array.from(arguments);
|
||||
}
|
||||
|
||||
it('should cap the number of arguments provided to `func`', () => {
|
||||
const actual = ['6', '8', '10'].map(ary(parseInt, 1));
|
||||
expect(actual).toEqual([6, 8, 10]);
|
||||
|
||||
const capped = ary(fn, 2);
|
||||
expect(capped('a', 'b', 'c', 'd')).toEqual(['a', 'b']);
|
||||
});
|
||||
|
||||
it('should use `func.length` if `n` is not given', () => {
|
||||
const capped = ary(fn);
|
||||
expect(capped('a', 'b', 'c', 'd')).toEqual(['a', 'b', 'c']);
|
||||
});
|
||||
|
||||
it('should treat a negative `n` as `0`', () => {
|
||||
const capped = ary(fn, -1);
|
||||
expect(capped('a', 'b', 'c', 'd')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should coerce `n` to an integer', () => {
|
||||
const values = ['1', 1.6, 'xyz'];
|
||||
const expected = [['a'], ['a'], []];
|
||||
|
||||
const actual = values.map((n: any) => {
|
||||
const capped = ary(fn, n);
|
||||
return capped('a', 'b');
|
||||
});
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should not force a minimum argument count', () => {
|
||||
const args = ['a', 'b', 'c'];
|
||||
const capped = ary(fn, 3);
|
||||
|
||||
const expected = args.map((arg, index) => args.slice(0, index));
|
||||
// eslint-disable-next-line prefer-spread
|
||||
const actual = expected.map(array => capped.apply(undefined, array));
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should use `this` binding of function', () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const capped = ary(function (this: unknown, _a: unknown, _b: unknown) {
|
||||
return this;
|
||||
}, 1);
|
||||
const object = { capped: capped };
|
||||
|
||||
expect(object.capped()).toBe(object);
|
||||
});
|
||||
|
||||
it('should use the existing `ary` if smaller', () => {
|
||||
const capped = ary(ary(fn, 1), 2);
|
||||
expect(capped('a', 'b', 'c', 'd')).toEqual(['a']);
|
||||
});
|
||||
|
||||
it('should work as an iteratee for methods like `_.map`', () => {
|
||||
const funcs = [fn].map(ary);
|
||||
const actual = funcs[0]('a', 'b', 'c');
|
||||
|
||||
expect(actual).toEqual(['a', 'b', 'c']);
|
||||
});
|
||||
});
|
21
src/compat/function/ary.ts
Normal file
21
src/compat/function/ary.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { ary as aryToolkit } from '../../function/ary.ts';
|
||||
|
||||
/**
|
||||
* Creates a function that invokes func, with up to n arguments, ignoring any additional arguments.
|
||||
*
|
||||
* @template F - The type of the function.
|
||||
* @param {F} func - The function to cap arguments for.
|
||||
* @param {number} n - The arity cap.
|
||||
* @returns {(...args: any[]) => ReturnType<F>} Returns the new capped function.
|
||||
*/
|
||||
export function ary<F extends (...args: any[]) => any>(func: F, n: number = func.length, guard?: unknown): ((...args: any[]) => ReturnType<F>) {
|
||||
if (guard) {
|
||||
n = func.length;
|
||||
}
|
||||
|
||||
if (Number.isNaN(n) || n < 0) {
|
||||
n = 0;
|
||||
}
|
||||
|
||||
return aryToolkit(func, n);
|
||||
};
|
@ -32,7 +32,9 @@ export { flatten } from './array/flatten.ts';
|
||||
export { flattenDeep } from './array/flattenDeep.ts';
|
||||
export { flattenDepth } from './array/flattenDepth.ts';
|
||||
export { zipObjectDeep } from './array/zipObjectDeep.ts';
|
||||
export { head as first } from '../index.ts';
|
||||
export { head as first } from '../array/head.ts';
|
||||
|
||||
export { ary } from './function/ary.ts';
|
||||
|
||||
export { get } from './object/get.ts';
|
||||
export { set } from './object/set.ts';
|
||||
|
@ -16,28 +16,6 @@ describe('ary', () => {
|
||||
expect(capped('a', 'b', 'c', 'd')).toEqual(['a', 'b']);
|
||||
});
|
||||
|
||||
it('should use `func.length` if `n` is not given', () => {
|
||||
const capped = ary(fn);
|
||||
expect(capped('a', 'b', 'c', 'd')).toEqual(['a', 'b', 'c']);
|
||||
});
|
||||
|
||||
it('should treat a negative `n` as `0`', () => {
|
||||
const capped = ary(fn, -1);
|
||||
expect(capped('a', 'b', 'c', 'd')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should coerce `n` to an integer', () => {
|
||||
const values = ['1', 1.6, 'xyz'];
|
||||
const expected = [['a'], ['a'], []];
|
||||
|
||||
const actual = values.map((n: any) => {
|
||||
const capped = ary(fn, n);
|
||||
return capped('a', 'b');
|
||||
});
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should not force a minimum argument count', () => {
|
||||
const args = ['a', 'b', 'c'];
|
||||
const capped = ary(fn, 3);
|
||||
@ -63,11 +41,4 @@ describe('ary', () => {
|
||||
const capped = ary(ary(fn, 1), 2);
|
||||
expect(capped('a', 'b', 'c', 'd')).toEqual(['a']);
|
||||
});
|
||||
|
||||
it('should work as an iteratee for methods like `_.map`', () => {
|
||||
const funcs = [fn].map(ary);
|
||||
const actual = funcs[0]('a', 'b', 'c');
|
||||
|
||||
expect(actual).toEqual(['a', 'b', 'c']);
|
||||
});
|
||||
});
|
||||
|
@ -1,22 +1,13 @@
|
||||
/**
|
||||
* Creates a function that invokes func, with up to n arguments, ignoring any additional arguments.
|
||||
*
|
||||
*
|
||||
* @template F - The type of the function.
|
||||
* @param {F} func - The function to cap arguments for.
|
||||
* @param {number} n - The arity cap.
|
||||
* @param {any} guard - Enables use as an iteratee for methods like `map`.
|
||||
* @returns {(...args: any[]) => ReturnType<F>} Returns the new capped function.
|
||||
*/
|
||||
export const ary = <F extends (...args: any[]) => any>(
|
||||
func: F,
|
||||
n: number = func.length,
|
||||
guard?: any
|
||||
): ((...args: any[]) => ReturnType<F>) => {
|
||||
n = guard ? func.length : Number.parseInt(n.toString());
|
||||
if (Number.isNaN(n) || n < 0) {
|
||||
n = 0;
|
||||
}
|
||||
export function ary<F extends (...args: any[]) => any>(func: F, n: number): ((...args: any[]) => ReturnType<F>) {
|
||||
return function (this: any, ...args: Parameters<F>) {
|
||||
return func.apply(this, args.slice(0, n));
|
||||
};
|
||||
|
@ -7,6 +7,6 @@ import { ary } from './ary.ts';
|
||||
* @param {F} func - The function to cap arguments for.
|
||||
* @returns {(...args: any[]) => ReturnType<F>} Returns the new capped function.
|
||||
*/
|
||||
export const unary = <F extends (...args: any[]) => any>(func: F): ((...args: any[]) => ReturnType<F>) => {
|
||||
export function unary<F extends (...args: any[]) => any>(func: F): ((...args: any[]) => ReturnType<F>) {
|
||||
return ary(func, 1);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user