mirror of
https://github.com/toss/es-toolkit.git
synced 2024-11-24 03:32:58 +03:00
feat(flowRight): implement flowRight (#603)
This commit is contained in:
parent
7eed956ee0
commit
75ed97afa0
21
benchmarks/performance/flowRight.bench.ts
Normal file
21
benchmarks/performance/flowRight.bench.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { bench, describe } from 'vitest';
|
||||
import { flowRight as flowRightToolkit } from 'es-toolkit';
|
||||
import { flowRight as flowRightLodash } from 'lodash';
|
||||
|
||||
const flowRight = flowRightToolkit;
|
||||
const flowRightLo = flowRightLodash;
|
||||
|
||||
describe('flowRight', () => {
|
||||
const add = (x: number, y: number) => x + y;
|
||||
const square = (n: number) => n * n;
|
||||
|
||||
bench('es-toolkit/flowRight', () => {
|
||||
const combined = flowRight(add, square);
|
||||
combined(1, 2);
|
||||
});
|
||||
|
||||
bench('lodash/flowRight', () => {
|
||||
const combined = flowRightLo(add, square);
|
||||
combined(1, 2);
|
||||
});
|
||||
});
|
50
docs/reference/function/flowRight.md
Normal file
50
docs/reference/function/flowRight.md
Normal file
@ -0,0 +1,50 @@
|
||||
# flowRight
|
||||
|
||||
Creates a function that returns the result of invoking the given functions with the `this` binding of the created function, where each successive invocation is supplied the return value of the previous.
|
||||
|
||||
This method is like [flow](./flow.md), except that it creates a function that invokes the given functions from right to left.
|
||||
|
||||
## Signature
|
||||
|
||||
```typescript
|
||||
function flowRight<R>(f: () => R): () => R;
|
||||
function flowRight<A extends any[], R>(f1: (...args: A) => R): (...args: A) => R;
|
||||
function flowRight<A extends any[], R1, R2>(f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R2;
|
||||
function flowRight<A extends any[], R1, R2, R3>(
|
||||
f3: (a: R2) => R3,
|
||||
f2: (a: R1) => R2,
|
||||
f1: (...args: A) => R1
|
||||
): (...args: A) => R3;
|
||||
function flowRight<A extends any[], R1, R2, R3, R4>(
|
||||
f4: (a: R3) => R4,
|
||||
f3: (a: R2) => R3,
|
||||
f2: (a: R1) => R2,
|
||||
f1: (...args: A) => R1
|
||||
): (...args: A) => R4;
|
||||
function flowRight<A extends any[], R1, R2, R3, R4, R5>(
|
||||
f5: (a: R4) => R5,
|
||||
f4: (a: R3) => R4,
|
||||
f3: (a: R2) => R3,
|
||||
f2: (a: R1) => R2,
|
||||
f1: (...args: A) => R1
|
||||
): (...args: A) => R5;
|
||||
function flowRight(...funcs: Array<(...args: any[]) => any>): (...args: any[]) => any;
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
- `funcs` (`Array<(...args: any[]) => any>`): The functions to invoke.
|
||||
|
||||
### Returns
|
||||
|
||||
(`(...args: any[]) => any`): The new composite function.
|
||||
|
||||
## Examples
|
||||
|
||||
```typescript
|
||||
const add = (x: number, y: number) => x + y;
|
||||
const square = (n: number) => n * n;
|
||||
|
||||
const combined = flowRight(square, add);
|
||||
console.log(combined(1, 2)); // => 9
|
||||
```
|
50
docs/zh_hans/reference/function/flowRight.md
Normal file
50
docs/zh_hans/reference/function/flowRight.md
Normal file
@ -0,0 +1,50 @@
|
||||
# flowRight
|
||||
|
||||
创建一个函数,该函数返回调用给定函数的结果,并将创建函数的 `this` 绑定传递给这些函数,每次调用时将上一次调用的返回值作为参数传递给下一次调用。
|
||||
|
||||
此方法类似于 [flow](./flow.md),但它创建的函数从右到左调用给定的函数。
|
||||
|
||||
## 签名
|
||||
|
||||
```typescript
|
||||
function flowRight<R>(f: () => R): () => R;
|
||||
function flowRight<A extends any[], R>(f1: (...args: A) => R): (...args: A) => R;
|
||||
function flowRight<A extends any[], R1, R2>(f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R2;
|
||||
function flowRight<A extends any[], R1, R2, R3>(
|
||||
f3: (a: R2) => R3,
|
||||
f2: (a: R1) => R2,
|
||||
f1: (...args: A) => R1
|
||||
): (...args: A) => R3;
|
||||
function flowRight<A extends any[], R1, R2, R3, R4>(
|
||||
f4: (a: R3) => R4,
|
||||
f3: (a: R2) => R3,
|
||||
f2: (a: R1) => R2,
|
||||
f1: (...args: A) => R1
|
||||
): (...args: A) => R4;
|
||||
function flowRight<A extends any[], R1, R2, R3, R4, R5>(
|
||||
f5: (a: R4) => R5,
|
||||
f4: (a: R3) => R4,
|
||||
f3: (a: R2) => R3,
|
||||
f2: (a: R1) => R2,
|
||||
f1: (...args: A) => R1
|
||||
): (...args: A) => R5;
|
||||
function flowRight(...funcs: Array<(...args: any[]) => any>): (...args: any[]) => any;
|
||||
```
|
||||
|
||||
### 参数
|
||||
|
||||
- `funcs` (`Array<(...args: any[]) => any>`): 需要调用的函数。
|
||||
|
||||
### 返回值
|
||||
|
||||
(`(...args: any[]) => any`): 新的组合函数。
|
||||
|
||||
## 示例
|
||||
|
||||
```typescript
|
||||
const add = (x: number, y: number) => x + y;
|
||||
const square = (n: number) => n * n;
|
||||
|
||||
const combined = flowRight(square, add);
|
||||
console.log(combined(1, 2)); // => 9
|
||||
```
|
53
src/function/flowRight.spec.ts
Normal file
53
src/function/flowRight.spec.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { flowRight } from './flowRight';
|
||||
import { curry } from '../compat/function/curry';
|
||||
import { head } from '../array';
|
||||
import { ary } from './ary';
|
||||
import { uniq } from '../array';
|
||||
|
||||
const add = function (x: number, y: number) {
|
||||
return x + y;
|
||||
};
|
||||
|
||||
const square = function (n: number) {
|
||||
return n * n;
|
||||
};
|
||||
|
||||
describe('flowRight', () => {
|
||||
it(`\`flowRight\` should supply each function with the return value of the previous`, () => {
|
||||
const fixed = function (n: number) {
|
||||
return n.toFixed(1);
|
||||
};
|
||||
const combined = flowRight(fixed, square, add);
|
||||
|
||||
expect(combined(1, 2)).toBe('9.0');
|
||||
});
|
||||
|
||||
it(`\`flowRight\` should return a new function`, () => {
|
||||
const noop = () => {};
|
||||
const combined = flowRight(noop);
|
||||
expect(combined).not.toBe(noop);
|
||||
});
|
||||
|
||||
it(`\`flowRight\` should work with a curried function and \`_.head\``, () => {
|
||||
const curried = curry((i: any) => i);
|
||||
|
||||
const combined = flowRight(curried, head);
|
||||
|
||||
expect(combined([1])).toBe(1);
|
||||
});
|
||||
|
||||
it(`\`flowRight\` should work with curried functions with placeholders`, () => {
|
||||
// TODO change to es-toolkit/compat - map
|
||||
const map = (array: any[], func: (...args: any[]) => any) => {
|
||||
return array.map(func);
|
||||
};
|
||||
const curried = curry(ary(map, 2), 2);
|
||||
const getProp = curried(curried.placeholder, (value: { a: any }) => value.a);
|
||||
const objects = [{ a: 1 }, { a: 2 }, { a: 1 }];
|
||||
|
||||
const combined = flowRight(uniq, getProp);
|
||||
|
||||
expect(combined(objects)).toEqual([1, 2]);
|
||||
});
|
||||
});
|
163
src/function/flowRight.ts
Normal file
163
src/function/flowRight.ts
Normal file
@ -0,0 +1,163 @@
|
||||
import { flow } from './flow.ts';
|
||||
|
||||
/**
|
||||
* Creates a function that returns the result of invoking the given functions with the `this` binding of the created function, where each successive invocation is supplied the return value of the previous.
|
||||
*
|
||||
* This method is like `flow` except that it creates a function that invokes the given functions from right to left.
|
||||
*
|
||||
* @param {() => R} f The function to invoke.
|
||||
* @returns {() => R} Returns the new composite function.
|
||||
*
|
||||
* @example
|
||||
* function noArgFunc() {
|
||||
* return 42;
|
||||
* }
|
||||
* const combined = flowRight(noArgFunc);
|
||||
* console.log(combined()); // 42
|
||||
*/
|
||||
export function flowRight<R>(f: () => R): () => R;
|
||||
/**
|
||||
* Creates a function that returns the result of invoking the given functions with the `this` binding of the created function, where each successive invocation is supplied the return value of the previous.
|
||||
*
|
||||
* This method is like `flow` except that it creates a function that invokes the given functions from right to left.
|
||||
*
|
||||
* @param {(...args: A) => R} f1 The function to invoke.
|
||||
* @returns {(...args: A) => R} Returns the new composite function.
|
||||
*
|
||||
* @example
|
||||
* function oneArgFunc(a: number) {
|
||||
* return a * 2;
|
||||
* }
|
||||
* const combined = flowRight(oneArgFunc);
|
||||
* console.log(combined(5)); // 10
|
||||
*/
|
||||
export function flowRight<A extends any[], R>(f1: (...args: A) => R): (...args: A) => R;
|
||||
/**
|
||||
* Creates a function that returns the result of invoking the given functions with the `this` binding of the created function, where each successive invocation is supplied the return value of the previous.
|
||||
*
|
||||
* This method is like `flow` except that it creates a function that invokes the given functions from right to left.
|
||||
*
|
||||
* @param {(a: R1) => R2} f2 The function to invoke.
|
||||
* @param {(...args: A) => R1} f1 The function to invoke.
|
||||
* @returns {(...args: A) => R2} Returns the new composite function.
|
||||
*
|
||||
* @example
|
||||
* const add = (x: number, y: number) => x + y;
|
||||
* const square = (n: number) => n * n;
|
||||
*
|
||||
* const combined = flowRight(square, add);
|
||||
* console.log(combined(1, 2)); // 9
|
||||
*/
|
||||
export function flowRight<A extends any[], R1, R2>(f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R2;
|
||||
/**
|
||||
* Creates a function that returns the result of invoking the given functions with the `this` binding of the created function, where each successive invocation is supplied the return value of the previous.
|
||||
*
|
||||
* This method is like `flow` except that it creates a function that invokes the given functions from right to left.
|
||||
*
|
||||
* @param {(a: R2) => R3} f3 The function to invoke.
|
||||
* @param {(a: R1) => R2} f2 The function to invoke.
|
||||
* @param {(...args: A) => R1} f1 The function to invoke.
|
||||
* @returns {(...args: A) => R3} Returns the new composite function.
|
||||
*
|
||||
* @example
|
||||
* const add = (x: number, y: number) => x + y;
|
||||
* const square = (n: number) => n * n;
|
||||
* const double = (n: number) => n * 2;
|
||||
*
|
||||
* const combined = flowRight(double, square, add);
|
||||
* console.log(combined(1, 2)); // 18
|
||||
*/
|
||||
export function flowRight<A extends any[], R1, R2, R3>(
|
||||
f3: (a: R2) => R3,
|
||||
f2: (a: R1) => R2,
|
||||
f1: (...args: A) => R1
|
||||
): (...args: A) => R3;
|
||||
/**
|
||||
* Creates a function that returns the result of invoking the given functions with the `this` binding of the created function, where each successive invocation is supplied the return value of the previous.
|
||||
*
|
||||
* This method is like `flow` except that it creates a function that invokes the given functions from right to left.
|
||||
*
|
||||
* @param {(a: R3) => R4} f4 The function to invoke.
|
||||
* @param {(a: R2) => R3} f3 The function to invoke.
|
||||
* @param {(a: R1) => R2} f2 The function to invoke.
|
||||
* @param {(...args: A) => R1} f1 The function to invoke.
|
||||
* @returns {(...args: A) => R4} Returns the new composite function.
|
||||
*
|
||||
* @example
|
||||
* const add = (x: number, y: number) => x + y;
|
||||
* const square = (n: number) => n * n;
|
||||
* const double = (n: number) => n * 2;
|
||||
* const toStr = (n: number) => n.toString();
|
||||
*
|
||||
* const combined = flowRight(toStr, double, square, add);
|
||||
* console.log(combined(1, 2)); // '18'
|
||||
*/
|
||||
export function flowRight<A extends any[], R1, R2, R3, R4>(
|
||||
f4: (a: R3) => R4,
|
||||
f3: (a: R2) => R3,
|
||||
f2: (a: R1) => R2,
|
||||
f1: (...args: A) => R1
|
||||
): (...args: A) => R4;
|
||||
/**
|
||||
* Creates a function that returns the result of invoking the given functions with the `this` binding of the created function, where each successive invocation is supplied the return value of the previous.
|
||||
*
|
||||
* This method is like `flow` except that it creates a function that invokes the given functions from right to left.
|
||||
*
|
||||
* @param {(a: R4) => R5} f5 The function to invoke.
|
||||
* @param {(a: R3) => R4} f4 The function to invoke.
|
||||
* @param {(a: R2) => R3} f3 The function to invoke.
|
||||
* @param {(a: R1) => R2} f2 The function to invoke.
|
||||
* @param {(...args: A) => R1} f1 The function to invoke.
|
||||
* @returns {(...args: A) => R5} Returns the new composite function.
|
||||
*
|
||||
* @example
|
||||
* const add = (x: number, y: number) => x + y;
|
||||
* const square = (n: number) => n * n;
|
||||
* const double = (n: number) => n * 2;
|
||||
* const toStr = (n: number) => n.toString();
|
||||
* const split = (s: string) => s.split('');
|
||||
*
|
||||
* const combined = flowRight(split, toStr, double, square, add);
|
||||
* console.log(combined(1, 2)); // ['1', '8']
|
||||
*/
|
||||
export function flowRight<A extends any[], R1, R2, R3, R4, R5>(
|
||||
f5: (a: R4) => R5,
|
||||
f4: (a: R3) => R4,
|
||||
f3: (a: R2) => R3,
|
||||
f2: (a: R1) => R2,
|
||||
f1: (...args: A) => R1
|
||||
): (...args: A) => R5;
|
||||
/**
|
||||
* Creates a function that returns the result of invoking the given functions with the `this` binding of the created function, where each successive invocation is supplied the return value of the previous.
|
||||
*
|
||||
* This method is like `flow` except that it creates a function that invokes the given functions from right to left.
|
||||
*
|
||||
* @param {(...args: any[]) => any} funcs The functions to invoke.
|
||||
* @returns {(...args: any[]) => any} Returns the new composite function.
|
||||
*
|
||||
* @example
|
||||
* const add = (x: number, y: number) => x + y;
|
||||
* const square = (n: number) => n * n;
|
||||
*
|
||||
* const combined = flowRight(square, add);
|
||||
* console.log(combined(1, 2)); // 9
|
||||
*/
|
||||
export function flowRight(...funcs: Array<(...args: any[]) => any>): (...args: any[]) => any;
|
||||
/**
|
||||
* Creates a function that returns the result of invoking the given functions with the `this` binding of the created function, where each successive invocation is supplied the return value of the previous.
|
||||
*
|
||||
* This method is like `flow` except that it creates a function that invokes the given functions from right to left.
|
||||
*
|
||||
* @param {(...args: any[]) => any} funcs The functions to invoke.
|
||||
* @returns {(...args: any[]) => any} Returns the new composite function.
|
||||
*
|
||||
* @example
|
||||
* const add = (x: number, y: number) => x + y;
|
||||
* const square = (n: number) => n * n;
|
||||
*
|
||||
* const combined = flowRight(square, add);
|
||||
* console.log(combined(1, 2)); // 9
|
||||
*/
|
||||
export function flowRight(...funcs: Array<(...args: any[]) => any>): (...args: any[]) => any {
|
||||
return flow(...funcs.reverse());
|
||||
}
|
@ -14,3 +14,4 @@ export { rest } from './rest.ts';
|
||||
export { curry } from './curry.ts';
|
||||
export { spread } from './spread.ts';
|
||||
export { flow } from './flow.ts';
|
||||
export { flowRight } from './flowRight.ts';
|
||||
|
Loading…
Reference in New Issue
Block a user