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 5 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);
});
});
46 changes: 46 additions & 0 deletions docs/ko/reference/array/without.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# without

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

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

## 인터페이스

```typescript
function without<T>(array: ArrayLike<T>, ...values: T[]): T[];
raon0211 marked this conversation as resolved.
Show resolved Hide resolved
```

### 파라미터

- `array` (`ArrayLike<T>`): 필터링할 배열.
- `values` (`...T[]`): 제외할 값들.
raon0211 marked this conversation as resolved.
Show resolved Hide resolved

### 반환 값

(`T[]`) 지정된 값을 제외한 새 배열.
raon0211 marked this conversation as resolved.
Show resolved Hide resolved

### 에러

명시적으로 예외를 발생시키지는 않지만, 입력이 유효한 배열이 아니거나 배열 길이가 유효하지 않은 경우 빈 배열을 반환합니다.

raon0211 marked this conversation as resolved.
Show resolved Hide resolved
## 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]
raon0211 marked this conversation as resolved.
Show resolved Hide resolved
```
48 changes: 48 additions & 0 deletions docs/reference/array/without.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# without

Creates an array excluding all given values using SameValueZero for equality comparisons.

This function takes an input array and returns a new array that excludes all values
specified in the additional arguments. It uses SameValueZero for equality comparisons,
meaning that it considers -0 and +0 as equal but treats NaN as unequal to itself.
raon0211 marked this conversation as resolved.
Show resolved Hide resolved

## Signature

```typescript
function without<T>(array: ArrayLike<T>, ...values: T[]): T[];
raon0211 marked this conversation as resolved.
Show resolved Hide resolved
```

### Parameters

- `array` (`ArrayLike<T>`): The array to filter.
- `values` (`...T[]`): The values to exclude.
raon0211 marked this conversation as resolved.
Show resolved Hide resolved

### Returns

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

### Throws

Does not throw explicitly but returns an empty array if the input is not a valid array or has invalid array length.

raon0211 marked this conversation as resolved.
Show resolved Hide resolved
## 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]);
});
});
29 changes: 29 additions & 0 deletions src/array/without.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Creates an array excluding all given values using SameValueZero for equality comparisons.
*
* This function takes an input array and returns a new array that excludes all values
* specified in the second argument. It uses SameValueZero for equality comparisons,
* meaning that it considers -0 and +0 as equal but treats NaN as unequal to itself.
raon0211 marked this conversation as resolved.
Show resolved Hide resolved
*
* @template T The type of elements in the array.
* @param {ArrayLike<T>} array - The array to filter.
raon0211 marked this conversation as resolved.
Show resolved Hide resolved
* @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: ArrayLike<T>, ...values: T[]): T[] {
raon0211 marked this conversation as resolved.
Show resolved Hide resolved
if (!array || typeof array.length !== 'number') {
return [];
}
raon0211 marked this conversation as resolved.
Show resolved Hide resolved
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