From 55cae8b0eb9817aab2ea93627779bffd2e8ffe45 Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Sun, 6 Oct 2024 16:20:26 +0800 Subject: [PATCH] feat(compat): implement dropRightWhile (#666) * feat(compat): implement dropRightWhile * Update benchmarks/performance/dropRightWhile.bench.ts --------- Co-authored-by: Sojin Park --- .../performance/dropRightWhile.bench.ts | 10 ++ benchmarks/performance/dropWhile.bench.ts | 10 ++ docs/ja/reference/array/dropRightWhile.md | 47 +++++++- docs/ko/reference/array/dropRightWhile.md | 48 +++++++- docs/reference/array/dropRightWhile.md | 48 +++++++- .../zh_hans/reference/array/dropRightWhile.md | 48 +++++++- src/array/dropRightWhile.ts | 9 +- src/array/dropWhile.ts | 2 +- src/compat/array/dropRightWhile.spec.ts | 47 ++++++++ src/compat/array/dropRightWhile.ts | 111 ++++++++++++++++++ src/compat/array/dropWhile.ts | 2 +- src/compat/index.ts | 1 + 12 files changed, 370 insertions(+), 13 deletions(-) create mode 100644 src/compat/array/dropRightWhile.spec.ts create mode 100644 src/compat/array/dropRightWhile.ts diff --git a/benchmarks/performance/dropRightWhile.bench.ts b/benchmarks/performance/dropRightWhile.bench.ts index cc751076..979cb424 100644 --- a/benchmarks/performance/dropRightWhile.bench.ts +++ b/benchmarks/performance/dropRightWhile.bench.ts @@ -1,8 +1,10 @@ import { bench, describe } from 'vitest'; import { dropRightWhile as dropRightWhileToolkit_ } from 'es-toolkit'; import { dropRightWhile as dropRightWhileLodash_ } from 'lodash'; +import { dropRightWhile as dropRightWhileToolkitCompat_ } from 'es-toolkit/compat'; const dropRightWhileToolkit = dropRightWhileToolkit_; +const dropRightWhileToolkitCompat = dropRightWhileToolkitCompat_; const dropRightWhileLodash = dropRightWhileLodash_; describe('dropRightWhile', () => { @@ -10,6 +12,10 @@ describe('dropRightWhile', () => { dropRightWhileToolkit([1.2, 2.3, 3.4], x => x < 2); }); + bench('es-toolkit (compat)/dropRightWhile', () => { + dropRightWhileToolkitCompat([1.2, 2.3, 3.4], x => x < 2); + }); + bench('lodash/dropRightWhile', () => { dropRightWhileLodash([1.2, 2.3, 3.4], x => x < 2); }); @@ -22,6 +28,10 @@ describe('dropRightWhile/largeArray', () => { dropRightWhileToolkit(largeArray, x => x < 5000); }); + bench('es-toolkit (compat)/dropRightWhile', () => { + dropRightWhileToolkitCompat(largeArray, x => x < 5000); + }); + bench('lodash/dropRightWhile', () => { dropRightWhileLodash(largeArray, x => x < 5000); }); diff --git a/benchmarks/performance/dropWhile.bench.ts b/benchmarks/performance/dropWhile.bench.ts index 6168842b..aa70ee7a 100644 --- a/benchmarks/performance/dropWhile.bench.ts +++ b/benchmarks/performance/dropWhile.bench.ts @@ -1,8 +1,10 @@ import { bench, describe } from 'vitest'; import { dropWhile as dropWhileToolkit_ } from 'es-toolkit'; +import { dropWhile as dropWhileToolkitCompat_ } from 'es-toolkit/compat'; import { dropWhile as dropWhileLodash_ } from 'lodash'; const dropWhileToolkit = dropWhileToolkit_; +const dropWhileToolkitCompat = dropWhileToolkitCompat_; const dropWhileLodash = dropWhileLodash_; describe('dropWhile', () => { @@ -10,6 +12,10 @@ describe('dropWhile', () => { dropWhileToolkit([1.2, 2.3, 3.4], x => x < 2); }); + bench('es-toolkit/compat/dropWhile', () => { + dropWhileToolkitCompat([1.2, 2.3, 3.4], x => x < 2); + }); + bench('lodash/dropWhile', () => { dropWhileLodash([1.2, 2.3, 3.4], x => x < 2); }); @@ -22,6 +28,10 @@ describe('dropWhile/largeArray', () => { dropWhileToolkit(largeArray, x => x < 5000); }); + bench('es-toolkit/compat/dropWhile', () => { + dropWhileToolkitCompat(largeArray, x => x < 5000); + }); + bench('lodash/dropWhile', () => { dropWhileLodash(largeArray, x => x < 5000); }); diff --git a/docs/ja/reference/array/dropRightWhile.md b/docs/ja/reference/array/dropRightWhile.md index ecca5ac9..58edd8e8 100644 --- a/docs/ja/reference/array/dropRightWhile.md +++ b/docs/ja/reference/array/dropRightWhile.md @@ -8,13 +8,13 @@ ## インターフェース ```typescript -function dropRightWhile(arr: T[], canContinueDropping: (item: T) => boolean): T[]; +function dropRightWhile(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => boolean): T[]; ``` ### パラメータ - `arr` (`T[]`): 要素を削除する配列。 -- `canContinueDropping` (`(item: T) => boolean`): 要素の削除を続けるかどうかを返す条件関数です。各要素に対して呼び出され、`true`を返す間は要素を削除します。 +- `canContinueDropping` (`(item: T, index: number, arr: T[]) => boolean`): 要素の削除を続けるかどうかを返す条件関数です。各要素に対して呼び出され、`true`を返す間は要素を削除します。 ### 戻り値 @@ -27,3 +27,46 @@ const array = [1, 2, 3, 2, 4, 5]; const result = dropRightWhile(array, x => x > 3); // 3以下の要素に遭遇するまで要素を削除するので、結果は[1, 2, 3, 2]になります。 ``` + +## Lodash 互換性 + +`es-toolkit/compat` から `dropRightWhile` をインポートすると、Lodash と互換になります。 +配列から要素を削除する条件を、さまざまな方法で指定できます。 + +- **検査関数**: 各要素に対して検査する関数を実行します。最初に`false`を返す要素が見つかるまで要素を削除します。 +- **部分オブジェクト**: 指定されたオブジェクトと部分的に一致しない要素が見つかるまで要素を削除します。 +- **プロパティ-値ペア**: 指定されたプロパティと値が一致しない要素が見つかるまで要素を削除します。 +- **プロパティ名**: 指定されたプロパティに対して偽と評価される値が見つかるまで要素を削除します。 + +### インターフェース + +```typescript +function dropRightWhile(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[]; +function dropRightWhile(arr: T[], objectToDrop: Partial): T[]; +function dropRightWhile(arr: T[], propertyToDrop: [keyof T, unknown]): T[]; +function dropRightWhile(arr: readonly T[], propertyToDrop: string): T[]; +``` + +### 例 + +```typescript +// 検査関数を使用した例 +const array1 = [5, 4, 3, 2, 1]; +const result1 = dropRightWhile(array1, x => x < 3); +// result1 は [5, 4, 3] になります。3未満の要素が削除されるためです。 + +// 部分オブジェクトを使用した例 +const array2 = [{ a: 1 }, { a: 2 }, { a: 3 }]; +const result2 = dropRightWhile(array2, { a: 3 }); +// result2 は [{ a: 1 }, { a: 2 }] になります。最後のオブジェクトが提供されたオブジェクトのプロパティと一致するためです。 + +// プロパティ-値ペアを使用した例 +const array3 = [{ id: 1 }, { id: 2 }, { id: 3 }]; +const result3 = dropRightWhile(array3, ['id', 3]); +// result3 は [{ id: 1 }, { id: 2 }] になります。最後のオブジェクトが id プロパティの値 3 と一致するためです。 + +// プロパティ名を使用した例 +const array4 = [{ isActive: false }, { isActive: true }, { isActive: true }]; +const result4 = dropRightWhile(array4, 'isActive'); +// result4 は [{ isActive: false }] になります。偽の isActive プロパティを持つ要素が見つかるまで要素が削除されるためです。 +``` diff --git a/docs/ko/reference/array/dropRightWhile.md b/docs/ko/reference/array/dropRightWhile.md index 4a987c70..e370ee0f 100644 --- a/docs/ko/reference/array/dropRightWhile.md +++ b/docs/ko/reference/array/dropRightWhile.md @@ -8,13 +8,13 @@ ## 인터페이스 ```typescript -function dropRightWhile(arr: T[], canContinueDropping: (item: T) => boolean): T[]; +function dropRightWhile(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => boolean): T[]; ``` ### 파라미터 - `arr` (`T[]`): 요소를 제거할 배열. -- `canContinueDropping` (`(item: T) => boolean`): 요소를 제거하는 것을 계속할지 반환하는 조건 함수예요. 각 요소에 대해서 호출되면서, `true`를 반환하는 동안 요소를 제거해요. +- `canContinueDropping` (`(item: T, index: number, arr: T[]) => boolean`): 요소를 제거하는 것을 계속할지 반환하는 조건 함수예요. 각 요소에 대해서 호출되면서, `true`를 반환하는 동안 요소를 제거해요. ### 반환 값 @@ -27,3 +27,47 @@ const array = [1, 2, 3, 2, 4, 5]; const result = dropRightWhile(array, x => x > 3); // 3보다 작거나 같은 요소를 만날 때까지 요소를 제거하므로, 결괏값은 [1, 2, 3, 2]이 되어요. ``` + +## Lodash와 호환성 + +`es-toolkit/compat`에서 `dropRightWhile`를 가져오면 lodash와 완전히 호환돼요. + +계속해서 배열에서 요소를 제거할 조건을 여러 방법들로 명시할 수 있어요. + +- **검사 함수**: 각각의 요소에 대해서 검사하는 함수를 실행해요. 처음으로 `false`를 반환하게 하는 요소가 있을 때까지 요소를 제거해요. +- **부분 객체**: 주어진 객체와 부분적으로 일치하지 않는 요소가 있을 때까지 요소를 제거해요. +- **프로퍼티-값 쌍**: 해당 프로퍼티와 값이 일치하지 않는 요소가 있을 때까지 요소를 제거해요. +- **프로퍼티 이름**: 해당 프로퍼티에 대해서 거짓으로 평가되는 값이 있을 때까지 요소를 제거해요. + +### 인터페이스 + +```typescript +function dropRightWhile(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[]; +function dropRightWhile(arr: T[], objectToDrop: Partial): T[]; +function dropRightWhile(arr: T[], propertyToDrop: [keyof T, unknown]): T[]; +function dropRightWhile(arr: readonly T[], propertyToDrop: string): T[]; +``` + +### 예시 + +```typescript +// 검사 함수를 사용하는 예시 +const array1 = [5, 4, 3, 2, 1]; +const result1 = dropRightWhile(array1, x => x < 3); +// 3보다 작은 요소가 제거되므로, 결과는 [5, 4, 3]가 돼요. + +// 부분 객체를 사용하는 예시 +const array2 = [{ a: 1 }, { a: 2 }, { a: 3 }]; +const result2 = dropRightWhile(array2, { a: 3 }); +// 마지막 요소만 부분 객체와 일치하므로, 결과는 [{ a: 1 }, { a: 2 }]가 돼요. + +// 프로퍼티-값 쌍을 사용하는 예시 +const array3 = [{ id: 1 }, { id: 2 }, { id: 3 }]; +const result3 = dropRightWhile(array3, ['id', 3]); +// 마지막 요소만 `id` 프로퍼티가 `3`과 일치하므로, 결과는 [{ id: 1 }, { id: 2 }]가 돼요. + +// 프로퍼티 이름을 사용하는 예시 +const array4 = [{ isActive: false }, { isActive: true }, { isActive: true }]; +const result4 = dropRightWhile(array4, 'isActive'); +// `isActive`가 참으로 평가되는 요소들이 있을 때까지 요소를 제거하므로, 결과는 [{ isActive: false }]이 돼요. +``` diff --git a/docs/reference/array/dropRightWhile.md b/docs/reference/array/dropRightWhile.md index 0dd2ecd9..75cf0a2a 100644 --- a/docs/reference/array/dropRightWhile.md +++ b/docs/reference/array/dropRightWhile.md @@ -8,13 +8,13 @@ predicate function returns `false`. It then returns a new array with the remaini ## Signature ```typescript -function dropRightWhile(arr: T[], canContinueDropping: (item: T) => boolean): T[]; +function dropRightWhile(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => boolean): T[]; ``` ### Parameters - `arr` (`T[]`): The array from which to drop elements. -- `canContinueDropping` (`(item: T) => boolean`): A predicate function that determines whether to continue dropping elements. The function is called with each element from the end, with each element, and dropping continues as long as it returns `true`. +- `canContinueDropping` (`(item: T, index: number, arr: T[]) => boolean`): A predicate function that determines whether to continue dropping elements. The function is called with each element from the end, with each element, and dropping continues as long as it returns `true`. ### Returns @@ -27,3 +27,47 @@ const array = [1, 2, 3, 4, 5]; const result = dropRightWhile(array, x => x > 3); // result will be [1, 2, 3] since elements greater than 3 are dropped from the end. ``` + +## Compatibility with Lodash + +Import `dropRightWhile` from `es-toolkit/compat` for full compatibility with lodash. + +You can specify the condition for dropping elements, and the array will remove items from the end as long as that condition evaluates to true. + +- **Predicate function**: You can provide a predicate function that will be applied to each item in the array. The function should return `true` for elements that should be dropped. Dropping continues until the predicate returns `false` for the first time. +- **Partial object**: You can also provide a partial object, and the function will drop elements from the array as long as their properties match the properties of the provided object. +- **Property-value pair**: Alternatively, you can specify a property-value pair, where the function will drop elements that have the specified property matching the given value. +- **Property name**: Lastly, you can provide a property name, and the function will drop elements from the array until it finds an element where the specified property has a truthy value. + +### Signature + +```typescript +function dropRightWhile(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[]; +function dropRightWhile(arr: T[], objectToDrop: Partial): T[]; +function dropRightWhile(arr: T[], propertyToDrop: [keyof T, unknown]): T[]; +function dropRightWhile(arr: readonly T[], propertyToDrop: string): T[]; +``` + +### Examples + +```typescript +// Example using a predicate function +const array1 = [5, 4, 3, 2, 1]; +const result1 = dropRightWhile(array1, x => x < 3); +// result1 will be [5, 4, 3] since elements less than 3 are dropped. + +// Example using a partial object +const array2 = [{ a: 1 }, { a: 2 }, { a: 3 }]; +const result2 = dropRightWhile(array2, { a: 3 }); +// result2 will be [{ a: 1 }, { a: 2 }] since the last object matches the properties of the provided object. + +// Example using a property-value pair +const array3 = [{ id: 1 }, { id: 2 }, { id: 3 }]; +const result3 = dropRightWhile(array3, ['id', 3]); +// result3 will be [{ id: 1 }, { id: 2 }] since the last object has the id property matching the value 3. + +// Example using a property name +const array4 = [{ isActive: false }, { isActive: true }, { isActive: true }]; +const result4 = dropRightWhile(array4, 'isActive'); +// result4 will be [{ isActive: false }] since it drops elements until it finds one with a falsy isActive property. +``` diff --git a/docs/zh_hans/reference/array/dropRightWhile.md b/docs/zh_hans/reference/array/dropRightWhile.md index f9611e65..f79a0d0a 100644 --- a/docs/zh_hans/reference/array/dropRightWhile.md +++ b/docs/zh_hans/reference/array/dropRightWhile.md @@ -7,13 +7,13 @@ ## 签名 ```typescript -function dropRightWhile(arr: T[], canContinueDropping: (item: T) => boolean): T[]; +function dropRightWhile(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => boolean): T[]; ``` ### 参数 - `arr` (`T[]`): 要从中移除元素的数组。 -- `canContinueDropping` (`(item: T) => boolean`): 一个谓词函数,用于确定是否继续移除元素。该函数将对数组中的每个元素调用,只要返回 `true`,移除操作就会继续。 +- `canContinueDropping` (`(item: T, index: number, arr: T[]) => boolean`): 一个谓词函数,用于确定是否继续移除元素。该函数将对数组中的每个元素调用,只要返回 `true`,移除操作就会继续。 ### 返回值 @@ -26,3 +26,47 @@ const array = [1, 2, 3, 4, 5]; const result = dropRightWhile(array, x => x > 3); // 结果将是 [1, 2, 3] 因为大于 3 的元素从末尾被移除了。 ``` + +## Lodash 兼容性 + +从 `es-toolkit/compat` 导入 `dropRightWhile` 以实现与 lodash 的完全兼容。 + +您可以指定移除元素的条件,只要该条件评估为 true,数组将从末尾移除项目。 + +- **谓词函数**:您可以提供一个谓词函数,该函数将应用于数组中的每个项目。该函数应返回 `true`,以指示应移除的元素。移除操作将持续进行,直到谓词第一次返回 `false`。 +- **部分对象**:您还可以提供一个部分对象,只要其属性与提供的对象的属性匹配,函数就会从数组中移除元素。 +- **属性-值对**:或者,您可以指定一个属性-值对,函数将移除具有指定属性且与给定值匹配的元素。 +- **属性名**:最后,您可以提供一个属性名,函数将从数组中移除元素,直到找到一个指定属性为真值的元素。 + +### 签名 + +```typescript +function dropRightWhile(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[]; +function dropRightWhile(arr: T[], objectToDrop: Partial): T[]; +function dropRightWhile(arr: T[], propertyToDrop: [keyof T, unknown]): T[]; +function dropRightWhile(arr: readonly T[], propertyToDrop: string): T[]; +``` + +### 示例 + +```typescript +// 使用谓词函数的示例 +const array1 = [5, 4, 3, 2, 1]; +const result1 = dropRightWhile(array1, x => x < 3); +// result1 将是 [5, 4, 3],因为小于 3 的元素被移除了。 + +// 使用部分对象的示例 +const array2 = [{ a: 1 }, { a: 2 }, { a: 3 }]; +const result2 = dropRightWhile(array2, { a: 3 }); +// result2 将是 [{ a: 1 }, { a: 2 }],因为最后一个对象与提供的对象的属性匹配。 + +// 使用属性-值对的示例 +const array3 = [{ id: 1 }, { id: 2 }, { id: 3 }]; +const result3 = dropRightWhile(array3, ['id', 3]); +// result3 将是 [{ id: 1 }, { id: 2 }],因为最后一个对象的 id 属性与值 3 匹配。 + +// 使用属性名的示例 +const array4 = [{ isActive: false }, { isActive: true }, { isActive: true }]; +const result4 = dropRightWhile(array4, 'isActive'); +// result4 将是 [{ isActive: false }],因为它会移除元素,直到找到一个 isActive 属性为假值的元素。 +``` diff --git a/src/array/dropRightWhile.ts b/src/array/dropRightWhile.ts index d0f70271..c75ebc04 100644 --- a/src/array/dropRightWhile.ts +++ b/src/array/dropRightWhile.ts @@ -6,7 +6,7 @@ * * @template T - The type of elements in the array. * @param {T[]} arr - The array from which to drop elements. - * @param {(item: T) => boolean} canContinueDropping - A predicate function that determines + * @param {(item: T, index: number, arr: T[]) => boolean} canContinueDropping - A predicate function that determines * whether to continue dropping elements. The function is called with each element from the end, * and dropping continues as long as it returns true. * @returns {T[]} A new array with the elements remaining after the predicate returns false. @@ -16,9 +16,12 @@ * const result = dropRightWhile(array, x => x > 3); * // result will be [1, 2, 3] since elements greater than 3 are dropped from the end. */ -export function dropRightWhile(arr: readonly T[], canContinueDropping: (item: T) => boolean): T[] { +export function dropRightWhile( + arr: readonly T[], + canContinueDropping: (item: T, index: number, arr: readonly T[]) => boolean +): T[] { for (let i = arr.length - 1; i >= 0; i--) { - if (!canContinueDropping(arr[i])) { + if (!canContinueDropping(arr[i], i, arr)) { return arr.slice(0, i + 1); } } diff --git a/src/array/dropWhile.ts b/src/array/dropWhile.ts index 21ebcc81..2ee98232 100644 --- a/src/array/dropWhile.ts +++ b/src/array/dropWhile.ts @@ -6,7 +6,7 @@ * * @template T - The type of elements in the array. * @param {T[]} arr - The array from which to drop elements. - * @param {(item: T) => boolean} canContinueDropping - A predicate function that determines + * @param {(item: T, index: number, arr: T[]) => boolean} canContinueDropping - A predicate function that determines * whether to continue dropping elements. The function is called with each element, and dropping * continues as long as it returns true. * @returns {T[]} A new array with the elements remaining after the predicate returns false. diff --git a/src/compat/array/dropRightWhile.spec.ts b/src/compat/array/dropRightWhile.spec.ts new file mode 100644 index 00000000..6d79bb81 --- /dev/null +++ b/src/compat/array/dropRightWhile.spec.ts @@ -0,0 +1,47 @@ +import { describe, expect, it } from 'vitest'; +import { dropRightWhile } from './dropRightWhile'; +import { slice } from '../_internal/slice'; + +/** + * @see https://github.com/lodash/lodash/blob/6a2cc1dfcf7634fea70d1bc5bd22db453df67b42/test/dropRightWhile.spec.js + */ +describe('dropRightWhile', () => { + const array = [1, 2, 3, 4]; + + const objects = [ + { a: 0, b: 0 }, + { a: 1, b: 1 }, + { a: 2, b: 2 }, + ]; + + it('should drop elements while `predicate` returns truthy', function () { + const actual = dropRightWhile(array, function (n) { + return n > 2; + }); + + expect(actual).toEqual([1, 2]); + }); + + it('should provide correct `predicate` arguments', function () { + let args; + + dropRightWhile(array, function () { + // eslint-disable-next-line prefer-rest-params + args = slice.call(arguments); + }); + + expect(args).toEqual([4, 3, array]); + }); + + it('should work with `_.matches` shorthands', function () { + expect(dropRightWhile(objects, { b: 2 })).toEqual(objects.slice(0, 2)); + }); + + it('should work with `_.matchesProperty` shorthands', function () { + expect(dropRightWhile(objects, ['b', 2])).toEqual(objects.slice(0, 2)); + }); + + it('should work with `_.property` shorthands', function () { + expect(dropRightWhile(objects, 'b')).toEqual(objects.slice(0, 1)); + }); +}); diff --git a/src/compat/array/dropRightWhile.ts b/src/compat/array/dropRightWhile.ts new file mode 100644 index 00000000..4726b389 --- /dev/null +++ b/src/compat/array/dropRightWhile.ts @@ -0,0 +1,111 @@ +import { dropRightWhile as dropRightWhileToolkit } from '../../array/dropRightWhile.ts'; +import { property } from '../object/property.ts'; +import { matches } from '../predicate/matches.ts'; +import { matchesProperty } from '../predicate/matchesProperty.ts'; + +/** + * Drops elements from the end of an array while the predicate function returns truthy. + * + * @template T - The type of elements in the array. + * @param {T[]} arr - The array from which to drop elements. + * @param {(item: T, index: number, arr: T[]) => unknown} canContinueDropping - A predicate function that determines + * whether to continue dropping elements. The function is called with each element, index, and array, and dropping + * continues as long as it returns true. + * @returns {T[]} A new array with the elements remaining after the predicate returns false. + * + * @example + * const array = [5, 4, 3, 2, 1]; + * const result = dropRightWhile(array, x => x < 3); + * result will be [5, 4, 3] since elements less than 3 are dropped. + */ +export function dropRightWhile( + arr: readonly T[], + canContinueDropping: (item: T, index: number, arr: readonly T[]) => unknown +): T[]; + +/** + * Drops elements from the end of an array while the specified object properties match. + * + * @template T - The type of elements in the array. + * @param {T[]} arr - The array from which to drop elements. + * @param {Partial} objectToDrop - An object specifying the properties to match for dropping elements. + * @returns {T[]} A new array with the elements remaining after the predicate returns false. + * + * @example + * const array = [{ a: 1 }, { a: 2 }, { a: 3 }]; + * const result = dropRightWhile(array, { a: 3 }); + * result will be [{ a: 1 }, { a: 2 }] since the last object matches the properties of the provided object. + */ +export function dropRightWhile(arr: readonly T[], objectToDrop: Partial): T[]; + +/** + * Drops elements from the end of an array while the specified property matches a given value. + * + * @template T - The type of elements in the array. + * @param {T[]} arr - The array from which to drop elements. + * @param {[keyof T, unknown]} propertyToDrop - A tuple containing the property key and the value to match for dropping elements. + * @returns {T[]} A new array with the elements remaining after the predicate returns false. + * + * @example + * const array = [{ id: 1 }, { id: 2 }, { id: 3 }]; + * const result = dropRightWhile(array, ['id', 3]); + * result will be [{ id: 1 }, { id: 2 }] since the last object has the id property matching the value 3. + */ +export function dropRightWhile(arr: readonly T[], propertyToDrop: [keyof T, unknown]): T[]; + +/** + * Drops elements from the end of an array while the specified property name matches. + * + * @template T - The type of elements in the array. + * @param {T[]} arr - The array from which to drop elements. + * @param {string} propertyToDrop - The name of the property to match for dropping elements. + * @returns {T[]} A new array with the elements remaining after the predicate returns false. + * + * @example + * const array = [{ isActive: false }, { isActive: true }, { isActive: true }]; + * const result = dropRightWhile(array, 'isActive'); + * result will be [{ isActive: false }] since it drops elements until it finds one with a falsy isActive property. + */ +export function dropRightWhile(arr: readonly T[], propertyToDrop: string): T[]; + +/** + * Removes elements from the end of an array until the predicate returns false. + * + * This function iterates over an array and drops elements from the end until the provided + * predicate function returns false. It then returns a new array with the remaining elements. + * + * @template T - The type of elements in the array. + * @param {T[]} arr - The array from which to drop elements. + * @param {(item: T, index: number, arr: T[]) => unknown} predicate - A predicate function that determines + * whether to continue dropping elements. The function is called with each element, index, and array, and dropping + * continues as long as it returns true. + * @returns {T[]} A new array with the elements remaining after the predicate returns false. + * + * @example + * const array = [3, 2, 1]; + * const result = dropRightWhile(array, (item, index, arr) => index <= 2); + * // Returns: [3] + */ +export function dropRightWhile( + arr: readonly T[], + predicate: ((item: T, index: number, arr: readonly T[]) => unknown) | Partial | [keyof T, unknown] | string +): T[] { + switch (typeof predicate) { + case 'function': { + return dropRightWhileToolkit(arr, (item, index, arr) => Boolean(predicate(item, index, arr))); + } + case 'object': { + if (Array.isArray(predicate) && predicate.length === 2) { + const key = predicate[0]; + const value = predicate[1]; + + return dropRightWhileToolkit(arr, matchesProperty(key, value)); + } else { + return dropRightWhileToolkit(arr, matches(predicate)); + } + } + case 'string': { + return dropRightWhileToolkit(arr, property(predicate)); + } + } +} diff --git a/src/compat/array/dropWhile.ts b/src/compat/array/dropWhile.ts index ab45fd44..e9714296 100644 --- a/src/compat/array/dropWhile.ts +++ b/src/compat/array/dropWhile.ts @@ -83,7 +83,7 @@ export function dropWhile(arr: readonly T[], propertyToDrop: string): T[]; * * @example * const array = [1, 2, 3]; - * const result = dropWhile(array, (item, index, arr) => index < 2); + * const result = dropWhile(array, (item, index, arr) => index <= 2); * // Returns: [3] */ export function dropWhile( diff --git a/src/compat/index.ts b/src/compat/index.ts index 709f7ec5..c3f98f96 100644 --- a/src/compat/index.ts +++ b/src/compat/index.ts @@ -31,6 +31,7 @@ export { concat } from './array/concat.ts'; export { difference } from './array/difference.ts'; export { drop } from './array/drop.ts'; export { dropWhile } from './array/dropWhile.ts'; +export { dropRightWhile } from './array/dropRightWhile.ts'; export { every } from './array/every.ts'; export { fill } from './array/fill.ts'; export { filter } from './array/filter.ts';