mirror of
https://github.com/toss/es-toolkit.git
synced 2024-11-27 14:57:44 +03:00
feat(flatMap): add flatMap function (#209)
* feat(flatMap): add flatMap function * docs: fix docs * Update src/array/flatMap.ts --------- Co-authored-by: Sojin Park <raon0211@gmail.com>
This commit is contained in:
parent
6a43cebe4f
commit
fec678cf34
29
benchmarks/flatMap.bench.ts
Normal file
29
benchmarks/flatMap.bench.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { bench, describe } from 'vitest';
|
||||
import { flatMap as flatMapToolkit } from 'es-toolkit';
|
||||
import { flatMapDepth as flatMapDepthLodash } from 'lodash';
|
||||
|
||||
function createNestedArray(arr: any[], depth: number) {
|
||||
let result = arr;
|
||||
|
||||
for (let i = 0; i < depth; i++) {
|
||||
result = [result];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
describe('flatMap', () => {
|
||||
const iterateeDepth = (item: number) => createNestedArray([item, item, item], 10);
|
||||
const arr = Array.from({ length: 30 }, (_, i) => i);
|
||||
|
||||
bench('es-toolkit/flatMap', () => {
|
||||
flatMapToolkit(arr, iterateeDepth, 10);
|
||||
});
|
||||
|
||||
bench('lodash/flatMapDepth', () => {
|
||||
flatMapDepthLodash(arr, iterateeDepth, 10);
|
||||
});
|
||||
|
||||
bench('js built-in/map.flat', () => {
|
||||
arr.map(iterateeDepth).flat(10);
|
||||
});
|
||||
});
|
@ -60,6 +60,7 @@ function sidebar(): DefaultTheme.Sidebar {
|
||||
{ text: 'dropRightWhile', link: '/reference/array/dropRightWhile' },
|
||||
{ text: 'fill', link: '/reference/array/fill' },
|
||||
{ text: 'toFilled', link: '/reference/array/toFilled' },
|
||||
{ text: 'flatMap', link: '/reference/array/flatMap' },
|
||||
{ text: 'flatten', link: '/reference/array/flatten' },
|
||||
{ text: 'flattenDeep', link: '/reference/array/flattenDeep' },
|
||||
{ text: 'forEachRight', link: '/reference/array/forEachRight' },
|
||||
|
@ -65,6 +65,7 @@ function sidebar(): DefaultTheme.Sidebar {
|
||||
},
|
||||
{ text: 'fill', link: '/ko/reference/array/fill' },
|
||||
{ text: 'toFilled', link: '/ko/reference/array/toFilled' },
|
||||
{ text: 'flatMap', link: '/ko/reference/array/flatMap' },
|
||||
{ text: 'flatten', link: '/ko/reference/array/flatten' },
|
||||
{ text: 'flattenDeep', link: '/ko/reference/array/flattenDeep' },
|
||||
{ text: 'forEachRight', link: '/reference/array/forEachRight' },
|
||||
|
40
docs/ko/reference/array/flatMap.md
Normal file
40
docs/ko/reference/array/flatMap.md
Normal file
@ -0,0 +1,40 @@
|
||||
# flatMap
|
||||
|
||||
중첩된 배열의 각 요소를 주어진 iteratee 함수로 매핑 후, 원하는 깊이까지 풀어서 평탄화해요.
|
||||
|
||||
JavaScript 언어에 포함된 [Array#flat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat)을 [Array#map](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map)과 함께 `map(iteratee).flat(depth)`으로 호출했을 때와 동일하게 동작하지만, 더 빨라요.
|
||||
|
||||
## 인터페이스
|
||||
|
||||
```typescript
|
||||
function flatMap<T, U, D extends number = 1>(
|
||||
arr: readonly T[],
|
||||
iteratee: (item: T) => U,
|
||||
depth?: D
|
||||
): Array<FlatArray<U[], D>>;
|
||||
```
|
||||
|
||||
### 파라미터
|
||||
|
||||
- `arr` (`T[]`): 평탄화할 중첩 배열이에요.
|
||||
- `iteratee` (`T[]`): 각 배열 요소를 매핑하는 함수에요.
|
||||
- `depth` (`D`): 평탄화할 깊이에요. 기본값은 1이에요.
|
||||
|
||||
### 반환 값
|
||||
|
||||
(`Array<FlatArray<U[], D>>`): 각 요소가 매핑되고, 원하는 깊이까지 평탄해진 새로운 배열이에요.
|
||||
|
||||
## 예시
|
||||
|
||||
```typescript
|
||||
const array = [1, 2, 3];
|
||||
|
||||
const result1 = flatMap(array, item => [item, item], 1);
|
||||
// [1, 1, 2, 2, 3, 3]를 반환해요.
|
||||
|
||||
const result2 = flatMap(array, item => [[item, item]], 2);
|
||||
// [1, 1, 2, 2, 3, 3]를 반환해요.
|
||||
|
||||
const result3 = flatMap(array, item => [[[item, item]]], 3);
|
||||
// [1, 1, 2, 2, 3, 3]를 반환해요.
|
||||
```
|
40
docs/reference/array/flatMap.md
Normal file
40
docs/reference/array/flatMap.md
Normal file
@ -0,0 +1,40 @@
|
||||
# flatMap
|
||||
|
||||
Map each element of a nested array to a given iteratee function, then flatten it to the desired depth.
|
||||
|
||||
It works the same as if you called [Array#flat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) with [Array#map](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map) as `map(iteratee).flat(depth)` in the JavaScript language, but it's faster.
|
||||
|
||||
## Signature
|
||||
|
||||
```typescript
|
||||
function flatMap<T, U, D extends number = 1>(
|
||||
arr: readonly T[],
|
||||
iteratee: (item: T) => U,
|
||||
depth?: D
|
||||
): Array<FlatArray<U[], D>>;
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
- `arr` (`T[]`): The array to flatten.
|
||||
- `iteratee` (`T[]`): A function that maps each array element.
|
||||
- `depth` (`D`): The depth to flatten, which defaults to 1.
|
||||
|
||||
### Returns
|
||||
|
||||
(`Array<FlatArray<U[], D>>`): A new array with each element mapped and flattened to the desired depth.
|
||||
|
||||
## Examples
|
||||
|
||||
```typescript
|
||||
const array = [1, 2, 3];
|
||||
|
||||
const result1 = flatMap(array, item => [item, item], 1);
|
||||
// Return [1, 1, 2, 2, 3, 3]
|
||||
|
||||
const result2 = flatMap(array, item => [[item, item]], 2);
|
||||
// Return [1, 1, 2, 2, 3, 3]
|
||||
|
||||
const result3 = flatMap(array, item => [[[item, item]]], 3);
|
||||
// Return [1, 1, 2, 2, 3, 3]
|
||||
```
|
36
src/array/flatMap.spec.ts
Normal file
36
src/array/flatMap.spec.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { flatMap } from './flatMap';
|
||||
|
||||
describe('flatMap', () => {
|
||||
const originArr = [1, 2, 3];
|
||||
|
||||
it('should map and flatten array of numbers with default depth', () => {
|
||||
const iteratee = (item: number) => [item, item];
|
||||
const expectedArr = [1, 1, 2, 2, 3, 3];
|
||||
|
||||
expect(flatMap(originArr, iteratee)).toEqual(expectedArr);
|
||||
});
|
||||
|
||||
it('should map and flatten array of numbers with specified depth', () => {
|
||||
const iteratee = (item: number) => [[[item, item]]];
|
||||
|
||||
const expectedArr1 = [[[1, 1]], [[2, 2]], [[3, 3]]];
|
||||
expect(flatMap(originArr, iteratee, 1)).toEqual(expectedArr1);
|
||||
|
||||
const expectedArr2 = [
|
||||
[1, 1],
|
||||
[2, 2],
|
||||
[3, 3],
|
||||
];
|
||||
expect(flatMap(originArr, iteratee, 2)).toEqual(expectedArr2);
|
||||
|
||||
const expectedArr3 = [1, 1, 2, 2, 3, 3];
|
||||
expect(flatMap(originArr, iteratee, 3)).toEqual(expectedArr3);
|
||||
});
|
||||
|
||||
it('should handle empty array', () => {
|
||||
const emptyArr: number[] = [];
|
||||
const result = flatMap(emptyArr, item => [item, item]);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
29
src/array/flatMap.ts
Normal file
29
src/array/flatMap.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { flatten } from './flatten';
|
||||
|
||||
/**
|
||||
* Maps each element in the array using the iteratee function and flattens the result up to the specified depth.
|
||||
*
|
||||
* @template T - The type of elements within the array.
|
||||
* @template U - The type of elements within the returned array from the iteratee function.
|
||||
* @template D - The depth to which the array should be flattened.
|
||||
* @param {T[]} arr - The array to flatten.
|
||||
* @param {(item: T) => U} iteratee - The function that produces the new array elements.
|
||||
* @param {D} depth - The depth level specifying how deep a nested array structure should be flattened. Defaults to 1.
|
||||
* @returns {Array<FlatArray<U[], D>>} The new array with the mapped and flattened elements.
|
||||
*
|
||||
* @example
|
||||
* const arr = [1, 2, 3];
|
||||
*
|
||||
* flatMap(arr, (item: number) => [item, item]);
|
||||
* // [1, 1, 2, 2, 3, 3]
|
||||
*
|
||||
* flatMap(arr, (item: number) => [[item, item]], 2);
|
||||
* // [1, 1, 2, 2, 3, 3]
|
||||
*/
|
||||
export function flatMap<T, U, D extends number>(
|
||||
arr: readonly T[],
|
||||
iteratee: (item: T) => U,
|
||||
depth = 1 as D
|
||||
): Array<FlatArray<U[], D>> {
|
||||
return flatten(arr.map(item => iteratee(item)), depth);
|
||||
}
|
@ -9,6 +9,7 @@ export { dropRight } from './dropRight.ts';
|
||||
export { dropRightWhile } from './dropRightWhile.ts';
|
||||
export { dropWhile } from './dropWhile.ts';
|
||||
export { fill } from './fill.ts';
|
||||
export { flatMap } from './flatMap.ts';
|
||||
export { flatten } from './flatten.ts';
|
||||
export { flattenDeep } from './flattenDeep.ts';
|
||||
export { forEachRight } from './forEachRight.ts';
|
||||
|
Loading…
Reference in New Issue
Block a user