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(collections): Returns an array excluding single given value #1074

Closed
wants to merge 11 commits into from
Closed
13 changes: 13 additions & 0 deletions collections/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,16 @@ console.assert(
],
);
```

## without

Returns an array excluding all given values.

```ts
import { without } from "./without.ts";

const numbers = [];
const withoutList = without([2, 1, 2, 3], 1, 2);

console.assert(withoutList === [3]);
```
33 changes: 33 additions & 0 deletions collections/without.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.

/** Used as the size to enable large array optimizations. */
const LARGE_ARRAY_SIZE = 200;

/**
* Returns an array excluding all given values.
*
* Example:
*
* ```ts
* import { without } from "./without.ts";
*
* const withoutList = without([2, 1, 2, 3], 1, 2);
*
* console.assert(withoutList === [ 3 ])
* ```
*/
export function without<T>(
array: Array<T>,
...values: Array<T>
getspooky marked this conversation as resolved.
Show resolved Hide resolved
): Array<T> {
if (array.length >= LARGE_ARRAY_SIZE) {
const set = new Set<T>();

for (const element of array) {
set.add(element);
}

array = Array.from(set);
getspooky marked this conversation as resolved.
Show resolved Hide resolved
}
return array.filter((value) => values.indexOf(value) === -1);
}
54 changes: 54 additions & 0 deletions collections/without_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.

import { assertEquals } from "../testing/asserts.ts";
import { without } from "./without.ts";

function withoutTest<I>(
input: Array<I>,
excluded: Array<I>,
expected: Array<I>,
message?: string,
) {
const actual = without(input, ...excluded);
assertEquals(actual, expected, message);
}

Deno.test({
name: "[collections/without] empty input",
fn() {
withoutTest([], [], []);
},
});

Deno.test({
name: "[collections/without] no matches",
fn() {
withoutTest([1, 2, 3, 4], [], [1, 2, 3, 4]);
},
});

Deno.test({
name: "[collections/without] single matche",
fn() {
withoutTest([1, 2, 3, 4], [1], [2, 3, 4]);
withoutTest([1, 2, 3, 2], [2], [1, 3]);
},
});

Deno.test({
name: "[collections/without] multiple matches",
fn() {
withoutTest([1, 2, 3, 4, 6], [1, 3, 6], [2, 4]);
withoutTest([2, 9, 8, 7, 6, 5], [7, 5], [2, 9, 8, 6]);
withoutTest([2, 9, 8, 7, 6, 5], [7, 5], [2, 9, 8, 6]);
},
});

Deno.test({
name: "[collections/without] large array size",
fn() {
const array = Array(200).fill(0);
array[0] = 1;
withoutTest(array, [0], [1]);
},
});