Skip to content

Commit

Permalink
fix(drop): support array-like args (#686)
Browse files Browse the repository at this point in the history
* fix(drop): support arrary-like args

* doc

* Update dropWhile.ts

* Update dropRightWhile.ts

---------

Co-authored-by: Sojin Park <[email protected]>
  • Loading branch information
D-Sketon and raon0211 authored Oct 9, 2024
1 parent 2740345 commit c95d40f
Show file tree
Hide file tree
Showing 18 changed files with 210 additions and 57 deletions.
10 changes: 10 additions & 0 deletions benchmarks/performance/dropRight.bench.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { bench, describe } from 'vitest';
import { dropRight as dropRightToolkit_ } from 'es-toolkit';
import { dropRight as dropRightToolkitCompat_ } from 'es-toolkit/compat';
import { dropRight as dropRightLodash_ } from 'lodash';

const dropRightToolkit = dropRightToolkit_;
const dropRightToolkitCompat = dropRightToolkitCompat_;
const dropRightLodash = dropRightLodash_;

describe('dropRight', () => {
bench('es-toolkit/dropRight', () => {
dropRightToolkit([1, 2, 3, 4, 5, 6], 3);
});

bench('es-toolkit/compat/dropRight', () => {
dropRightToolkitCompat([1, 2, 3, 4, 5, 6], 3);
});

bench('lodash/dropRight', () => {
dropRightLodash([1, 2, 3, 4, 5, 6], 3);
});
Expand All @@ -22,6 +28,10 @@ describe('dropRight/largeArray', () => {
dropRightToolkit(largeArray, 5000);
});

bench('es-toolkit/compat/dropRight', () => {
dropRightToolkitCompat(largeArray, 5000);
});

bench('lodash/dropRight', () => {
dropRightLodash(largeArray, 5000);
});
Expand Down
11 changes: 7 additions & 4 deletions docs/ja/reference/array/dropRightWhile.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,13 @@ const result = dropRightWhile(array, x => x > 3);
### インターフェース

```typescript
function dropRightWhile<T>(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[];
function dropRightWhile<T>(arr: T[], objectToDrop: Partial<T>): T[];
function dropRightWhile<T>(arr: T[], propertyToDrop: [keyof T, unknown]): T[];
function dropRightWhile<T>(arr: readonly T[], propertyToDrop: string): T[];
function dropRightWhile<T>(
arr: ArrayLike<T> | null | undefined,
canContinueDropping: (item: T, index: number, arr: T[]) => unknown
): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, objectToDrop: Partial<T>): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: [keyof T, unknown]): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: string): T[];
```

###
Expand Down
11 changes: 7 additions & 4 deletions docs/ja/reference/array/dropWhile.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,13 @@ const result = dropWhile(array, x => x < 3);
### インターフェース

```typescript
function dropWhile<T>(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[];
function dropWhile<T>(arr: T[], objectToDrop: Partial<T>): T[];
function dropWhile<T>(arr: T[], propertyToDrop: [keyof T, unknown]): T[];
function dropWhile<T>(arr: readonly T[], propertyToDrop: string): T[];
function dropWhile<T>(
arr: ArrayLike<T> | null | undefined,
canContinueDropping: (item: T, index: number, arr: T[]) => unknown
): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, objectToDrop: Partial<T>): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: [keyof T, unknown]): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: string): T[];
```

###
Expand Down
11 changes: 7 additions & 4 deletions docs/ko/reference/array/dropRightWhile.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,13 @@ const result = dropRightWhile(array, x => x > 3);
### 인터페이스

```typescript
function dropRightWhile<T>(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[];
function dropRightWhile<T>(arr: T[], objectToDrop: Partial<T>): T[];
function dropRightWhile<T>(arr: T[], propertyToDrop: [keyof T, unknown]): T[];
function dropRightWhile<T>(arr: readonly T[], propertyToDrop: string): T[];
function dropRightWhile<T>(
arr: ArrayLike<T> | null | undefined,
canContinueDropping: (item: T, index: number, arr: T[]) => unknown
): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, objectToDrop: Partial<T>): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: [keyof T, unknown]): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: string): T[];
```

### 예시
Expand Down
11 changes: 7 additions & 4 deletions docs/ko/reference/array/dropWhile.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,13 @@ const result = dropWhile(array, x => x < 3);
### 인터페이스

```typescript
function dropWhile<T>(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[];
function dropWhile<T>(arr: T[], objectToDrop: Partial<T>): T[];
function dropWhile<T>(arr: T[], propertyToDrop: [keyof T, unknown]): T[];
function dropWhile<T>(arr: readonly T[], propertyToDrop: string): T[];
function dropWhile<T>(
arr: ArrayLike<T> | null | undefined,
canContinueDropping: (item: T, index: number, arr: T[]) => unknown
): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, objectToDrop: Partial<T>): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: [keyof T, unknown]): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: string): T[];
```

### 예시
Expand Down
11 changes: 7 additions & 4 deletions docs/reference/array/dropRightWhile.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,13 @@ You can specify the condition for dropping elements, and the array will remove i
### Signature

```typescript
function dropRightWhile<T>(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[];
function dropRightWhile<T>(arr: T[], objectToDrop: Partial<T>): T[];
function dropRightWhile<T>(arr: T[], propertyToDrop: [keyof T, unknown]): T[];
function dropRightWhile<T>(arr: readonly T[], propertyToDrop: string): T[];
function dropRightWhile<T>(
arr: ArrayLike<T> | null | undefined,
canContinueDropping: (item: T, index: number, arr: T[]) => unknown
): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, objectToDrop: Partial<T>): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: [keyof T, unknown]): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: string): T[];
```

### Examples
Expand Down
11 changes: 7 additions & 4 deletions docs/reference/array/dropWhile.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,13 @@ You can specify the condition for dropping elements, and the array will remove i
### Signature

```typescript
function dropWhile<T>(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[];
function dropWhile<T>(arr: T[], objectToDrop: Partial<T>): T[];
function dropWhile<T>(arr: T[], propertyToDrop: [keyof T, unknown]): T[];
function dropWhile<T>(arr: readonly T[], propertyToDrop: string): T[];
function dropWhile<T>(
arr: ArrayLike<T> | null | undefined,
canContinueDropping: (item: T, index: number, arr: T[]) => unknown
): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, objectToDrop: Partial<T>): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: [keyof T, unknown]): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: string): T[];
```

### Examples
Expand Down
11 changes: 7 additions & 4 deletions docs/zh_hans/reference/array/dropRightWhile.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,13 @@ const result = dropRightWhile(array, x => x > 3);
### 签名

```typescript
function dropRightWhile<T>(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[];
function dropRightWhile<T>(arr: T[], objectToDrop: Partial<T>): T[];
function dropRightWhile<T>(arr: T[], propertyToDrop: [keyof T, unknown]): T[];
function dropRightWhile<T>(arr: readonly T[], propertyToDrop: string): T[];
function dropRightWhile<T>(
arr: ArrayLike<T> | null | undefined,
canContinueDropping: (item: T, index: number, arr: T[]) => unknown
): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, objectToDrop: Partial<T>): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: [keyof T, unknown]): T[];
function dropRightWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: string): T[];
```

### 示例
Expand Down
8 changes: 4 additions & 4 deletions docs/zh_hans/reference/array/dropWhile.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ const result = dropWhile(array, x => x < 3);
### 签名

```typescript
function dropWhile<T>(arr: T[], canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[];
function dropWhile<T>(arr: T[], objectToDrop: Partial<T>): T[];
function dropWhile<T>(arr: T[], propertyToDrop: [keyof T, unknown]): T[];
function dropWhile<T>(arr: readonly T[], propertyToDrop: string): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, canContinueDropping: (item: T, index: number, arr: T[]) => unknown): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined objectToDrop: Partial<T>): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: [keyof T, unknown]): T[];
function dropWhile<T>(arr: ArrayLike<T> | null | undefined, propertyToDrop: string): T[];
```

### 示例
Expand Down
14 changes: 14 additions & 0 deletions src/compat/array/drop.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest';
import { drop } from './drop';
import { args } from '../_internal/args';

/**
* @see https://github.com/lodash/lodash/blob/6a2cc1dfcf7634fea70d1bc5bd22db453df67b42/test/drop.spec.js#L1
Expand Down Expand Up @@ -30,4 +31,17 @@ describe('drop', () => {
it('should return an empty array when the collection is null or undefined', () => {
expect(drop(null, 2)).toEqual([]);
});

it('should return an empty array when the collection is not array-like', () => {
// @ts-expect-error - invalid argument
expect(drop(1, 2)).toEqual([]);
// @ts-expect-error - invalid argument
expect(drop(true, 2)).toEqual([]);
});

it('should support array-like', () => {
expect(drop({ 0: 1, 1: 2, length: 2 }, 1)).toEqual([2]);
expect(drop('123', 2)).toEqual(['3']);
expect(drop(args, 1)).toEqual([2, 3]);
});
});
13 changes: 7 additions & 6 deletions src/compat/array/drop.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { drop as dropToolkit } from '../../array/drop.ts';
import { isArrayLike } from '../predicate/isArrayLike.ts';

/**
* Removes a specified number of elements from the beginning of an array and returns the rest.
*
* This function takes an array and a number, and returns a new array with the specified number
* of elements removed from the start.
*
* @template T - The type of elements in the array.
* @param { T[] | null | undefined} collection - - The array from which to drop elements.
* @param {ArrayLike<T> | null | undefined} collection - The array from which to drop elements.
* @param {number} itemsCount - The number of elements to drop from the beginning of the array.
* @returns {T[]} A new array with the specified number of elements removed from the start.
*
Expand All @@ -14,12 +17,10 @@
* const result = drop(array, 2);
* result will be [3, 4, 5] since the first two elements are dropped.
*/
export function drop<T>(collection: readonly T[] | null | undefined, itemsCount: number): T[] {
if (collection === null || collection === undefined) {
export function drop<T>(collection: ArrayLike<T> | null | undefined, itemsCount: number): T[] {
if (!isArrayLike(collection)) {
return [];
}

itemsCount = Math.max(itemsCount, 0);

return collection.slice(itemsCount);
return dropToolkit(Array.from(collection), itemsCount);
}
20 changes: 19 additions & 1 deletion src/compat/array/dropRight.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest';
import { dropRight } from '../../array/dropRight';
import { dropRight } from './dropRight';
import { args } from '../_internal/args';

/**
* @see https://github.com/lodash/lodash/blob/6a2cc1dfcf7634fea70d1bc5bd22db453df67b42/test/dropRight.spec.js#L1
Expand All @@ -26,4 +27,21 @@ describe('dropRight', () => {
it('should coerce `n` to an integer', () => {
expect(dropRight(array, 1.6)).toEqual([1, 2]);
});

it('should return an empty array when the collection is null or undefined', () => {
expect(dropRight(null, 2)).toEqual([]);
});

it('should return an empty array when the collection is not array-like', () => {
// @ts-expect-error - invalid argument
expect(dropRight(1, 2)).toEqual([]);
// @ts-expect-error - invalid argument
expect(dropRight(true, 2)).toEqual([]);
});

it('should support array-like', () => {
expect(dropRight({ 0: 1, 1: 2, length: 2 }, 1)).toEqual([1]);
expect(dropRight('123', 2)).toEqual(['1']);
expect(dropRight(args, 1)).toEqual([1, 2]);
});
});
26 changes: 26 additions & 0 deletions src/compat/array/dropRight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { dropRight as dropRightToolkit } from '../../array/dropRight.ts';
import { isArrayLike } from '../predicate/isArrayLike.ts';

/**
* Removes a specified number of elements from the end of an array and returns the rest.
*
* This function takes an array and a number, and returns a new array with the specified number
* of elements removed from the end.
*
* @template T - The type of elements in the array.
* @param {ArrayLike<T> | null | undefined} collection - The array from which to drop elements.
* @param {number} itemsCount - The number of elements to drop from the end of the array.
* @returns {T[]} A new array with the specified number of elements removed from the end.
*
* @example
* const array = [1, 2, 3, 4, 5];
* const result = dropRight(array, 2);
* // result will be [1, 2, 3] since the last two elements are dropped.
*/
export function dropRight<T>(collection: ArrayLike<T> | null | undefined, itemsCount: number): T[] {
if (!isArrayLike(collection)) {
return [];
}

return dropRightToolkit(Array.from(collection), itemsCount);
}
19 changes: 19 additions & 0 deletions src/compat/array/dropRightWhile.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest';
import { dropRightWhile } from './dropRightWhile';
import { args } from '../_internal/args';
import { slice } from '../_internal/slice';

/**
Expand Down Expand Up @@ -44,4 +45,22 @@ describe('dropRightWhile', () => {
it('should work with `_.property` shorthands', function () {
expect(dropRightWhile(objects, 'b')).toEqual(objects.slice(0, 1));
});

it('should return an empty array when the collection is null or undefined', () => {
expect(dropRightWhile(null, () => true)).toEqual([]);
expect(dropRightWhile(undefined, () => true)).toEqual([]);
});

it('should return an empty array when the collection is not array-like', () => {
// @ts-expect-error - invalid argument
expect(dropRightWhile(1, () => true)).toEqual([]);
// @ts-expect-error - invalid argument
expect(dropRightWhile(true, () => true)).toEqual([]);
});

it('should support array-like', () => {
expect(dropRightWhile({ 0: 1, 1: 2, 2: 3, length: 3 }, i => i > 1)).toEqual([1]);
expect(dropRightWhile('123', i => Number(i) > 1)).toEqual(['1']);
expect(dropRightWhile(args, i => i > 1)).toEqual([1]);
});
});
Loading

0 comments on commit c95d40f

Please sign in to comment.