-
Notifications
You must be signed in to change notification settings - Fork 323
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(flatten): add faltten (#137) * fix: fix lint * fix: fix test code description * test(flatten): add test case * Update docs/ko/reference/array/flatten.md * Update docs/ko/reference/array/flatten.md * Update docs/ko/reference/array/flatten.md * Update docs/reference/array/flatten.md --------- Co-authored-by: Sojin Park <raon0211@gmail.com>
- Loading branch information
Showing
8 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { bench, describe } from 'vitest'; | ||
import { flatten as flattenToolkit } from 'es-toolkit'; | ||
import { flattenDepth as flattenDepthLodash } from 'lodash'; | ||
|
||
const createNestedArray = (values: any[]) => { | ||
if (values.length === 0) { | ||
return []; | ||
} | ||
const [first, ...rest] = values; | ||
return [first, createNestedArray(rest)]; | ||
}; | ||
|
||
describe('flatten', () => { | ||
const arr = createNestedArray(Array.from({ length: 30 }, (_, index) => index)); | ||
|
||
bench('es-toolkit/flatten', () => { | ||
flattenToolkit(arr, 30); | ||
}); | ||
|
||
bench('lodash/flattenDepth', () => { | ||
flattenDepthLodash(arr, 30); | ||
}); | ||
|
||
bench('js built-in/flat', () => { | ||
arr.flat(30); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# flatten | ||
|
||
중첩된 배열을 원하는 깊이까지 풀어서 평탄화해요. | ||
|
||
JavaScript 언어에 포함된 [Array#flat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat)과 동일하게 동작하지만, 더 빨라요. | ||
|
||
## 인터페이스 | ||
|
||
```typescript | ||
function flatten<T, D extends number = 1>(arr: T[], depth?: D): Array<FlatArray<T[], D>>; | ||
``` | ||
|
||
### 파라미터 | ||
|
||
- `arr` (`T[]`): 평탄화할 중첩 배열이에요. | ||
- `depth` (`D`): 평탄화할 깊이에요. 기본값은 1이에요. | ||
|
||
### 반환 값 | ||
|
||
(`Array<FlatArray<T[], D>>`): 원하는 깊이까지 평탄해진 새로운 배열이에요. | ||
|
||
## 예시 | ||
|
||
```typescript | ||
const originArr = [1, [2, 3], [4, [5, 6]]]; | ||
|
||
const array1 = flatten(originArr); | ||
// [1, 2, 3, 4, [5, 6]]를 반환해요. | ||
|
||
const array2 = flatten(originArr, 1); | ||
// [1, 2, 3, 4, [5, 6]]를 반환해요. | ||
|
||
const array3 = flatten(originArr, 2); | ||
// [1, 2, 3, 4, 5, 6]를 반환해요. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# flatten | ||
|
||
Flattens the nested array given as an argument to the desired depth. | ||
|
||
It works the same as [Array.prototype.flat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) provided by default in JavaScript and returns the same type. However, its performance is superior. | ||
|
||
## Signature | ||
|
||
```typescript | ||
function flatten<T, D extends number = 1>(arr: T[], depth?: D): Array<FlatArray<T[], D>>; | ||
``` | ||
|
||
### Parameters | ||
|
||
- `arr` (`T[]`): The array to flatten. | ||
- `depth` (`D`): The depth to flatten, which defaults to 1. | ||
|
||
### Returns | ||
|
||
(`Array<FlatArray<T[], D>>`) A new array that has been flattened. | ||
|
||
## Examples | ||
|
||
```typescript | ||
const originArr = [1, [2, 3], [4, [5, 6]]]; | ||
|
||
const array1 = flatten(originArr); | ||
// Return [1, 2, 3, 4, [5, 6]] | ||
|
||
const array2 = flatten(originArr, 1); | ||
// Return [1, 2, 3, 4, [5, 6]] | ||
|
||
const array3 = flatten(originArr, 2); | ||
// Return [1, 2, 3, 4, 5, 6] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
import { flatten } from '.'; | ||
|
||
describe('flatten', () => { | ||
const originArr = [1, [2, [3, [4]]]]; | ||
|
||
it('should flatten a array to the default depth of 1', () => { | ||
const expectedArr = [1, 2, [3, [4]]]; | ||
|
||
expect(flatten(originArr)).toEqual(expectedArr); | ||
expect(originArr.flat()).toEqual(expectedArr); | ||
}); | ||
|
||
it('should flatten a deeply nested array to the specified depth', () => { | ||
const expectedArr1 = [1, 2, [3, [4]]]; | ||
expect(flatten(originArr, 1)).toEqual(expectedArr1); | ||
expect(originArr.flat(1)).toEqual(expectedArr1); | ||
|
||
const expectedArr2 = [1, 2, 3, [4]]; | ||
expect(flatten(originArr, 2)).toEqual(expectedArr2); | ||
expect(originArr.flat(2)).toEqual(expectedArr2); | ||
|
||
const expectedArr3 = [1, 2, 3, 4]; | ||
expect(flatten(originArr, 3)).toEqual(expectedArr3); | ||
expect(originArr.flat(3)).toEqual(expectedArr3); | ||
|
||
expect(flatten(originArr, Infinity)).toEqual(expectedArr3); | ||
expect(originArr.flat(Infinity)).toEqual(expectedArr3); | ||
}); | ||
|
||
it('should return the same array if depth is 0 or NaN or negative', () => { | ||
const expectedArr = [1, [2, [3, [4]]]]; | ||
|
||
expect(flatten(originArr, 0)).toEqual(expectedArr); | ||
expect(originArr.flat(0)).toEqual(expectedArr); | ||
|
||
expect(flatten(originArr, NaN)).toEqual(expectedArr); | ||
expect(originArr.flat(NaN)).toEqual(expectedArr); | ||
|
||
expect(flatten(originArr, -1)).toEqual(expectedArr); | ||
expect(originArr.flat(-1)).toEqual(expectedArr); | ||
}); | ||
|
||
it('should flatten arrays to the specified depth considering floating point values', () => { | ||
const expectedArr1 = [1, 2, [3, [4]]]; | ||
expect(flatten(originArr, 1.3)).toEqual(expectedArr1); | ||
expect(originArr.flat(1.3)).toEqual(expectedArr1); | ||
|
||
const expectedArr2 = [1, 2, 3, [4]]; | ||
expect(flatten(originArr, 2.5)).toEqual(expectedArr2); | ||
expect(originArr.flat(2.5)).toEqual(expectedArr2); | ||
|
||
const expectedArr3 = [1, 2, 3, 4]; | ||
expect(flatten(originArr, 3.9)).toEqual(expectedArr3); | ||
expect(originArr.flat(3.9)).toEqual(expectedArr3); | ||
}); | ||
|
||
it('should handle empty array', () => { | ||
const originArr: number[] = []; | ||
|
||
expect(flatten(originArr, 2)).toEqual([]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/** | ||
* Flattens an array up to the specified depth. | ||
* | ||
* @template T - The type of elements within the array. | ||
* @template D - The depth to which the array should be flattened. | ||
* @param {T[]} arr - The array to flatten. | ||
* @param {D} depth - The depth level specifying how deep a nested array structure should be flattened. Defaults to 1. | ||
* @returns {Array<FlatArray<T[], D>>} A new array that has been flattened. | ||
* | ||
* @example | ||
* const arr = flatten([1, [2, 3], [4, [5, 6]]], 1); | ||
* // Returns: [1, 2, 3, 4, [5, 6]] | ||
* | ||
* const arr = flatten([1, [2, 3], [4, [5, 6]]], 2); | ||
* // Returns: [1, 2, 3, 4, 5, 6] | ||
*/ | ||
export function flatten<T, D extends number = 1>(arr: readonly T[], depth = 1 as D): Array<FlatArray<T[], D>> { | ||
const result: Array<FlatArray<T[], D>> = []; | ||
const flooredDepth = Math.floor(depth); | ||
|
||
const recursive = (arr: readonly T[], currentDepth: number) => { | ||
for (const item of arr) { | ||
if (Array.isArray(item) && currentDepth < flooredDepth) { | ||
recursive(item, currentDepth + 1); | ||
} else { | ||
result.push(item as FlatArray<T[], D>); | ||
} | ||
} | ||
}; | ||
|
||
recursive(arr, 0); | ||
return result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters