Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(without): Add without function #115

Merged
merged 8 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions benchmarks/without.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { bench, describe } from 'vitest';
import { without as withoutEsToolkit } from 'es-toolkit';
import { without as withoutLodash } from 'lodash';

const generateArray = (length: number, max: number) => Array.from({ length }, () => Math.floor(Math.random() * max));

describe('without, small arrays', () => {
const array = [1, 2, 3, 4, 5];
const values = [2, 4];

bench('es-toolkit/without', () => {
withoutEsToolkit(array, ...values);
});

bench('lodash/without', () => {
withoutLodash(array, ...values);
});
});

describe('without, large arrays', () => {
const array = generateArray(10000, 1000);
const values = generateArray(100, 1000);

bench('es-toolkit/without', () => {
withoutEsToolkit(array, ...values);
});

bench('lodash/without', () => {
withoutLodash(array, ...values);
});
});
42 changes: 42 additions & 0 deletions docs/ko/reference/array/without.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# without

배열에서 주어진 값을 제거한 새로운 배열을 만들어요.

값이 같은지는 [SameValueZero](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-samevaluezero) 기준으로 비교하기 때문에, `NaN`과도 사용할 수 있어요.

## 인터페이스

```typescript
function without<T>(array: T[], ...values: T[]): T[];
```

### 파라미터

- `array` (`T[]`): 값을 제거할 배열.
- `values` (`...T[]`): 제거할 값.

### 반환 값

(`T[]`) 주어진 값을 제외한 새 배열.

## Examples

```typescript
import { without } from 'es-toolkit/array';

// 배열에서 지정된 값을 제거합니다
without([1, 2, 3, 4, 5], 2, 4);
// 결과 값: [1, 3, 5]

// 배열에서 지정된 문자열 값을 제거합니다
without(['a', 'b', 'c', 'a'], 'a');
// 결과 값: ['b', 'c']

// 지정된 값이 배열에 없는 경우를 처리합니다
without([1, 2, 3], 4, 5);
// 결과 값: [1, 2, 3]

// 다른 유형의 값을 포함한 경우를 처리합니다
without([1, '2', 3, '4'], 2, '4');
// 결과 값: [1, '2', 3]
```
42 changes: 42 additions & 0 deletions docs/reference/array/without.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# without

Creates an array that excludes all specified values.

It correctly excludes `NaN`, as it compares values using [SameValueZero](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-samevaluezero).

## Signature

```typescript
function without<T>(array: T[], ...values: T[]): T[];
```

### Parameters

- `array` (`T[]`): The array to exclude values.
- `values` (`...T[]`): The values to exclude.

### Returns

(`T[]`) A new array without the specified values.

## Examples

```typescript
import { without } from 'es-toolkit/array';

// Removes the specified values from the array
without([1, 2, 3, 4, 5], 2, 4);
// Returns: [1, 3, 5]

// Removes specified string values from the array
without(['a', 'b', 'c', 'a'], 'a');
// Returns: ['b', 'c']

// Handles cases where none of the specified values are in the array
without([1, 2, 3], 4, 5);
// Returns: [1, 2, 3]

// Handles cases with different types of values
without([1, '2', 3, '4'], 2, '4');
// Returns: [1, '2', 3]
```
1 change: 1 addition & 0 deletions src/array/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export { unionWith } from './unionWith.ts';
export { uniq } from './uniq.ts';
export { uniqBy } from './uniqBy.ts';
export { uniqWith } from './uniqWith.ts';
export { without } from './without.ts';
export { xor } from './xor.ts';
export { xorBy } from './xorBy.ts';
export { xorWith } from './xorWith.ts';
Expand Down
41 changes: 41 additions & 0 deletions src/array/without.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { describe, expect, it } from 'vitest';
import { without } from './without';

describe('without', () => {
it('should return an empty array when the input array is empty', () => {
expect(without([], 1, 2, 3)).toEqual([]);
});

it('should return the same array when no values are provided to exclude', () => {
expect(without([1, 2, 3])).toEqual([1, 2, 3]);
});

it('should return a new array excluding the specified values', () => {
expect(without([1, 2, 3, 4, 5], 2, 4)).toEqual([1, 3, 5]);
expect(without(['a', 'b', 'c', 'a'], 'a')).toEqual(['b', 'c']);
});

it('should handle cases where none of the specified values are in the array', () => {
expect(without([1, 2, 3], 4, 5)).toEqual([1, 2, 3]);
});

it('should handle cases with different types of values', () => {
expect(without([1, '2', 3, '4'], 2, '4')).toEqual([1, '2', 3]);
expect(without([1, '1', 2, '2'], 1, '2')).toEqual(['1', 2]);
});

it('should return an empty array when input is not a valid array', () => {
expect(without(null as any, 1, 2)).toEqual([]);
expect(without(undefined as any, 1, 2)).toEqual([]);
expect(without({ length: 'invalid' } as any, 1, 2)).toEqual([]);
});

raon0211 marked this conversation as resolved.
Show resolved Hide resolved
it('should handle NaN values correctly', () => {
expect(without([NaN, 1, 2, NaN, 3], NaN)).toEqual([1, 2, 3]);
});

it('should treat +0 and -0 as equal', () => {
expect(without([0, -0, 1, 2], 0)).toEqual([1, 2]);
expect(without([0, -0, 1, 2], -0)).toEqual([1, 2]);
});
});
24 changes: 24 additions & 0 deletions src/array/without.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Creates an array that excludes all specified values.
*
* It correctly excludes `NaN`, as it compares values using [SameValueZero](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-samevaluezero).
*
* @template T The type of elements in the array.
* @param {T[]} array - The array to filter.
* @param {...T[]} values - The values to exclude.
* @returns {T[]} A new array without the specified values.
*
* @example
* // Removes the specified values from the array
* without([1, 2, 3, 4, 5], 2, 4);
* // Returns: [1, 3, 5]
*
* @example
* // Removes specified string values from the array
* without(['a', 'b', 'c', 'a'], 'a');
* // Returns: ['b', 'c']
*/
export function without<T>(array: readonly T[], ...values: T[]): T[] {
const valuesSet = new Set(values);
return Array.prototype.filter.call(array, item => !valuesSet.has(item));
raon0211 marked this conversation as resolved.
Show resolved Hide resolved
}
Loading