diff --git a/docs/.vitepress/en.mts b/docs/.vitepress/en.mts index 8c229d9e..fc061247 100644 --- a/docs/.vitepress/en.mts +++ b/docs/.vitepress/en.mts @@ -84,6 +84,7 @@ function sidebar(): DefaultTheme.Sidebar { { text: 'max (compat)', link: '/reference/compat/array/max' }, { text: 'orderBy', link: '/reference/array/orderBy' }, { text: 'partition', link: '/reference/array/partition' }, + { text: 'pullAt', link: '/reference/array/pullAt' }, { text: 'sample', link: '/reference/array/sample' }, { text: 'sampleSize', link: '/reference/array/sampleSize' }, { text: 'shuffle', link: '/reference/array/shuffle' }, diff --git a/docs/.vitepress/ja.mts b/docs/.vitepress/ja.mts index a60a2b1a..c5c930d5 100644 --- a/docs/.vitepress/ja.mts +++ b/docs/.vitepress/ja.mts @@ -83,6 +83,7 @@ function sidebar(): DefaultTheme.Sidebar { { text: 'max (compat)', link: '/ja/reference/compat/array/max' }, { text: 'orderBy', link: '/ja/reference/array/orderBy' }, { text: 'partition', link: '/ja/reference/array/partition' }, + { text: 'pullAt', link: '/ja/reference/array/pullAt' }, { text: 'sample', link: '/ja/reference/array/sample' }, { text: 'sampleSize', link: '/ja/reference/array/sampleSize' }, { text: 'shuffle', link: '/ja/reference/array/shuffle' }, diff --git a/docs/.vitepress/ko.mts b/docs/.vitepress/ko.mts index 0f715deb..50390979 100644 --- a/docs/.vitepress/ko.mts +++ b/docs/.vitepress/ko.mts @@ -92,6 +92,7 @@ function sidebar(): DefaultTheme.Sidebar { { text: 'max (호환성)', link: '/ko/reference/compat/array/max' }, { text: 'orderBy', link: '/ko/reference/array/orderBy' }, { text: 'partition', link: '/ko/reference/array/partition' }, + { text: 'pullAt', link: '/ko/reference/array/pullAt' }, { text: 'sample', link: '/ko/reference/array/sample' }, { text: 'sampleSize', link: '/ko/reference/array/sampleSize' }, { text: 'shuffle', link: '/ko/reference/array/shuffle' }, diff --git a/docs/.vitepress/zh_hans.mts b/docs/.vitepress/zh_hans.mts index 74e62f9a..f6268437 100644 --- a/docs/.vitepress/zh_hans.mts +++ b/docs/.vitepress/zh_hans.mts @@ -81,6 +81,7 @@ function sidebar(): DefaultTheme.Sidebar { { text: 'max (兼容性)', link: '/zh_hans/reference/compat/array/max' }, { text: 'orderBy', link: '/zh_hans/reference/array/orderBy' }, { text: 'partition', link: '/zh_hans/reference/array/partition' }, + { text: 'pullAt', link: '/zh_hans/reference/array/pullAt' }, { text: 'sample', link: '/zh_hans/reference/array/sample' }, { text: 'sampleSize', link: '/zh_hans/reference/array/sampleSize' }, { text: 'shuffle', link: '/zh_hans/reference/array/shuffle' }, diff --git a/docs/ja/reference/array/pullAt.md b/docs/ja/reference/array/pullAt.md new file mode 100644 index 00000000..9bb3d7da --- /dev/null +++ b/docs/ja/reference/array/pullAt.md @@ -0,0 +1,29 @@ +# pullAt + +指定されたインデックスの位置から配列の要素を削除し、削除された要素を返します。 + +## インターフェース + +```typescript +function pullAt(arr: T[], indicesToRemove: number[]): T[]; +``` + +### パラメータ + +- `arr` (`T[]`): 要素を削除する元の配列。 +- `indicesToRemove` (`number[]`): 削除する要素の位置を指定するインデックスの配列。 + +### 戻り値 + +(`T[]`): 元の配列から削除された要素を含む新しい配列。 + +## 例 + +```typescript +import { pullAt } from 'es-toolkit/array'; + +const numbers = [10, 20, 30, 40, 50]; +const removed = pullAt(numbers, [1, 3, 4]); +console.log(removed); // [20, 40, 50] +console.log(numbers); // [10, 30] +``` diff --git a/docs/ko/reference/array/pullAt.md b/docs/ko/reference/array/pullAt.md index 12ad353f..bf61c41b 100644 --- a/docs/ko/reference/array/pullAt.md +++ b/docs/ko/reference/array/pullAt.md @@ -1,33 +1,29 @@ # pullAt -특정 인덱스 요소들을 찾아 새로운 배열을 반환해 주는 함수에요. - -이 함수는 파라미터로 특정 인덱스 요소를 조회할 배열과 인덱스 정보를 담은 배열을 받아요. - -첫 번재 파라미터로 받은 배열을 기준으로 두 번째로 받은 인덱스 정보를 담은 배열로 특정 요소를 조회해요. - -인덱스로 조회된 요소는 순서대로 조합되어 새로운 배열로 반환되고, 조회된 배열은 조회한 인덱스 값을 제외한 나머지로 이루어지게 돼요. +특정 인덱스에 있는 요소들을 제거하고, 제거된 요소들을 반환해요. ## 인터페이스 ```typescript -function pullAt(array: T[], indexes: number[]): Array; +function pullAt(arr: T[], indicesToRemove: number[]): T[]; ``` ### 파라미터 -- `arr` (`T[]`): 특정 인덱스 요소를 조회할 배열이에요. -- `indexes`: (`number[]`): 배열의 인덱스 요소를 찾기 위한 인덱스 정보를 담은 배열이에요. +- `arr` (`T[]`): 요소를 제거할 배열. +- `indicesToRemove` (`number[]`): 요소를 제거할 인덱스. ### 반환 값 -(`Array`): 배열의 특정 인덱스 요소를 찾아 조합한 새로운 배열을 반환해요. +(`T[]`): 제거된 요소들의 배열. ## 예시 ```typescript -const array = [0, 1, 2, 3, 4, 5]; -const indexes = [1, 3, 5]; -const result = pullAt(array, indexes); -// 조회할 인덱스는 1, 3, 5 이므로, 결과는 [1, 3, 5]이고 원본 배열은 [0, 2, 4]로 변화가 이루어져요. +import { pullAt } from 'es-toolkit/array'; + +const numbers = [10, 20, 30, 40, 50]; +const removed = pullAt(numbers, [1, 3, 4]); +console.log(removed); // [20, 40, 50] +console.log(numbers); // [10, 30] ``` diff --git a/docs/reference/array/pullAt.md b/docs/reference/array/pullAt.md new file mode 100644 index 00000000..0b16c61a --- /dev/null +++ b/docs/reference/array/pullAt.md @@ -0,0 +1,29 @@ +# pullAt + +Removes elements from an array at specified indices and returns the removed elements. + +## Signature + +```typescript +function pullAt(arr: T[], indicesToRemove: number[]): T[]; +``` + +### Parameters + +- `arr` (`T[]`): The array from which elements will be removed. +- `indicesToRemove` (`number[]`): An array of indices specifying the positions of elements to remove. + +### Returns + +(`T[]`): An array containing the elements that were removed from the original array. + +## Examples + +```typescript +import { pullAt } from 'es-toolkit/array'; + +const numbers = [10, 20, 30, 40, 50]; +const removed = pullAt(numbers, [1, 3, 4]); +console.log(removed); // [20, 40, 50] +console.log(numbers); // [10, 30] +``` diff --git a/docs/zh_hans/reference/array/pullAt.md b/docs/zh_hans/reference/array/pullAt.md new file mode 100644 index 00000000..adcf3621 --- /dev/null +++ b/docs/zh_hans/reference/array/pullAt.md @@ -0,0 +1,29 @@ +# pullAt + +从数组中删除指定索引处的元素,并返回被删除的元素。 + +## 签名 + +```typescript +function pullAt(arr: T[], indicesToRemove: number[]): T[]; +``` + +### 参数 + +- `arr` (`T[]`): 要从中删除元素的原始数组。 +- `indicesToRemove` (`number[]`): 指定要删除元素位置的索引数组。 + +### 返回值 + +(`T[]`): 包含从原始数组中删除的元素的新数组。 + +## 示例 + +```typescript +import { pullAt } from 'es-toolkit/array'; + +const numbers = [10, 20, 30, 40, 50]; +const removed = pullAt(numbers, [1, 3, 4]); +console.log(removed); // [20, 40, 50] +console.log(numbers); // [10, 30] +``` diff --git a/src/array/pullAt.spec.ts b/src/array/pullAt.spec.ts index 7b424721..f9220ce5 100644 --- a/src/array/pullAt.spec.ts +++ b/src/array/pullAt.spec.ts @@ -41,4 +41,23 @@ describe('pullAt', () => { expect(array).toStrictEqual([0, 1, 2, 3, 4, 5]); expect(result).toStrictEqual([]); }); + + it('should work with unsorted indexes', () => { + const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; + const actual = pullAt(array, [1, 3, 11, 7, 5, 9]); + + expect(array).toEqual([1, 3, 5, 7, 9, 11]); + expect(actual).toEqual([2, 4, 12, 8, 6, 10]); + }); + + it('should work with objects', () => { + const foo = { foo: 1 }; + const bar = { foo: 2 }; + + const arr = [foo, bar, foo]; + const result = pullAt(arr, [2]); + + expect(arr).toEqual([foo, bar]); + expect(result).toEqual([foo]); + }); }); diff --git a/src/array/pullAt.ts b/src/array/pullAt.ts index 7dcdfa70..3c5c6e50 100644 --- a/src/array/pullAt.ts +++ b/src/array/pullAt.ts @@ -1,29 +1,34 @@ +import { at } from './at.ts'; +import { uniq } from './uniq.ts'; + /** - * Returns new array of index search of the original array and change original array. + * Removes elements from an array at specified indices and returns the removed elements. + * + * This function first retrieves the elements at the specified indices using the `at` function, + * then removes the elements from the original array, and finally returns the removed elements. + * The indices are deduplicated and sorted before removal to ensure correct behavior when + * removing multiple elements. + * + * @template T + * @param {T[]} arr - The array from which elements will be removed. + * @param {number[]} indicesToRemove - An array of indices specifying the positions of elements to remove. + * @returns {T[]} An array containing the elements that were removed from the original array. * - * @template T - The type of elements of array. - * @param {T[]} arr - The original array to pullAt. - * @param {number[]} indexes - The array for index search of the original array to pullAt. - * @returns {T[]} - A new array with pullAt * @example - * const arr = ['%', { a: '2' }, '3', '5', '6']; - * const result = pullAt(arr, [1, 3]); - * // result will be new array with pullAt - * // arr: ['%', '3', '6']; - * // result: [{ a: '2' }, '5'] + * import { pullAt } from './pullAt'; + * + * const numbers = [10, 20, 30, 40, 50]; + * const removed = pullAt(numbers, [1, 3, 4]); + * console.log(removed); // [20, 40, 50] + * console.log(numbers); // [10, 30] */ -export function pullAt(arr: T[], indexes: number[]): Array { - const result: Array = []; +export function pullAt(arr: T[], indicesToRemove: number[]): Array { + const removed = at(arr, indicesToRemove); + const indices = new Set(indicesToRemove.slice().sort((x, y) => y - x)); - for (const index of indexes) { - result.push(arr[index]); + for (const index of indices) { + arr.splice(index, 1); } - for (const value of result) { - if (typeof value !== 'undefined' && arr.includes(value)) { - arr.splice(arr.indexOf(value), 1); - } - } - - return result; + return removed; }