diff --git a/.changeset/tidy-falcons-hide.md b/.changeset/tidy-falcons-hide.md new file mode 100644 index 00000000..6c5d3370 --- /dev/null +++ b/.changeset/tidy-falcons-hide.md @@ -0,0 +1,5 @@ +--- +'@modern-kit/utils': minor +--- + +feat(utils): swap 함수 추가 - @Gaic4o diff --git a/docs/docs/utils/array/swap.md b/docs/docs/utils/array/swap.md new file mode 100644 index 00000000..9bae5886 --- /dev/null +++ b/docs/docs/utils/array/swap.md @@ -0,0 +1,33 @@ +# swap + +배열 내 두 요소의 위치를 교환하며, 옵션에 따라 원본 배열을 수정하거나 새로운 배열을 반환합니다. + +## Code +[🔗 실제 구현 코드 확인](https://github.com/modern-agile-team/modern-kit/blob/main/packages/utils/src/array/swap/index.ts) + +## Interface +```ts title="typescript" +function swap( + arr: T[] | readonly T[], + i: number, + j: number, + options?: { immutable?: boolean } +): T[] +``` + +## Usage +```ts title="typescript" +import { swap } from '@modern-kit/utils'; + +const arr = [1, 2, 3]; +swap(arr, 0, 2); // [3, 2, 1] +console.log(arr); // [3, 2, 1] (원본 배열 유지) +``` + +```ts title="typescript" +import { swap } from '@modern-kit/utils'; + +const newArr = swap(arr, 0, 2, { immutable: true }); // [3, 2, 1] +console.log(arr); // [1, 2, 3] (원본 배열 유지) +console.log(newArr); // [3, 2, 1] (새로운 배열 반환) +``` diff --git a/packages/utils/src/array/index.ts b/packages/utils/src/array/index.ts index 535ca5f1..83bc9f24 100644 --- a/packages/utils/src/array/index.ts +++ b/packages/utils/src/array/index.ts @@ -15,5 +15,6 @@ export * from './intersectionWithDuplicates'; export * from './mapRight'; export * from './partition'; export * from './shuffle'; +export * from './swap'; export * from './union'; export * from './uniq'; diff --git a/packages/utils/src/array/shuffle/index.ts b/packages/utils/src/array/shuffle/index.ts index 4f951d8c..2fcbcd05 100644 --- a/packages/utils/src/array/shuffle/index.ts +++ b/packages/utils/src/array/shuffle/index.ts @@ -1,6 +1,4 @@ -const swap = (arr: T[], i: number, j: number) => { - [arr[i], arr[j]] = [arr[j], arr[i]]; -}; +import { swap } from '../../array/swap'; /** * @description 배열의 요소들의 순서를 무작위로 섞습니다. diff --git a/packages/utils/src/array/swap/index.ts b/packages/utils/src/array/swap/index.ts new file mode 100644 index 00000000..5ba2917c --- /dev/null +++ b/packages/utils/src/array/swap/index.ts @@ -0,0 +1,37 @@ +/** + * @description 배열 내의 두 요소의 위치를 교환합니다. + * + * 기본적으로 원본 배열을 직접 수정하지만, immutable 옵션을 통해 + * 새로운 배열을 반환하도록 설정할 수 있습니다. + * + * @template T - 배열 요소의 유형입니다. + * @param {T[] | readonly T[]} arr - 요소를 교환할 대상 배열입니다. + * @param {number} i - 교환할 첫 번째 요소의 인덱스입니다. + * @param {number} j - 교환할 두 번째 요소의 인덱스입니다. + * @param options - 추가 옵션을 포함하는 객체입니다. + * @param {boolean} [options.immutable=false] - true일 경우, 원본 배열을 수정하지 않고 새 배열을 반환합니다. + * @returns {T[]} 요소가 교환된 배열입니다. immutable이 false면 원본 배열, true면 새로운 배열입니다. + * + * @example + * const arr = [1, 2, 3]; + * swap(arr, 0, 2); // [3, 2, 1] + * console.log(arr); // [3, 2, 1] (원본 배열 유지) + * + * @example + * const arr = [1, 2, 3]; + * const newArr = swap(arr, 0, 2, { immutable: true }); // [3, 2, 1] + * console.log(arr); // [1, 2, 3] (원본 배열 유지) + * console.log(newArr); // [3, 2, 1] (새로운 배열 반환) + */ +export function swap( + arr: T[] | readonly T[], + i: number, + j: number, + options?: { immutable?: boolean } +): T[] { + const immutable = options?.immutable ?? false; + const result = immutable ? [...arr] : (arr as T[]); + + [result[i], result[j]] = [result[j], result[i]]; + return result; +} diff --git a/packages/utils/src/array/swap/swap.spec.ts b/packages/utils/src/array/swap/swap.spec.ts new file mode 100644 index 00000000..442b84fe --- /dev/null +++ b/packages/utils/src/array/swap/swap.spec.ts @@ -0,0 +1,35 @@ +import { describe, it, expect } from 'vitest'; +import { swap } from '.'; + +describe('swap', () => { + it('should swap elements in a array', () => { + const arr = [1, 2, 3]; + const result = swap(arr, 0, 2); + + expect(result).toEqual([3, 2, 1]); + expect(arr).toBe(result); + }); + + it('should swap elements in an immutable way when specified', () => { + const arr = [1, 2, 3]; + const result = swap(arr, 0, 2, { immutable: true }); + + expect(result).toEqual([3, 2, 1]); + expect(arr).not.toBe(result); + }); + + it('should swap elements in a mutable way when specified', () => { + const arr = [1, 2, 3]; + const result = swap(arr, 0, 2, { immutable: false }); + + expect(result).toEqual([3, 2, 1]); + expect(arr).toBe(result); + }); + + it('should return the same array if swapping an element with itself', () => { + const arr = [1, 2, 3]; + const result = swap(arr, 1, 1); + expect(result).toEqual([1, 2, 3]); + expect(result).toBe(arr); + }); +});