Skip to content

Commit

Permalink
feat(micro-dash): add reject()
Browse files Browse the repository at this point in the history
Closes #33
  • Loading branch information
ersimont committed May 5, 2021
1 parent f7830e6 commit 915db96
Show file tree
Hide file tree
Showing 6 changed files with 430 additions and 0 deletions.
6 changes: 6 additions & 0 deletions projects/micro-dash-sizes/src/app/collection/reject.lodash.ts
@@ -0,0 +1,6 @@
import reject from 'lodash-es/reject';

console.log(
reject([1], () => true),
reject({ a: 1 }, () => false),
);
@@ -0,0 +1,6 @@
import { reject } from '@s-libs/micro-dash';

console.log(
reject([1], () => true),
reject({ a: 1 }, () => false),
);
1 change: 1 addition & 0 deletions projects/micro-dash/src/lib/collection/index.ts
Expand Up @@ -9,6 +9,7 @@ export { includes } from './includes';
export { keyBy } from './key-by';
export { map } from './map';
export { reduce } from './reduce';
export { reject } from './reject';
export { reduceRight } from './reduce-right';
export { sample } from './sample';
export { sampleSize } from './sample-size';
Expand Down
81 changes: 81 additions & 0 deletions projects/micro-dash/src/lib/collection/reject.spec.ts
@@ -0,0 +1,81 @@
import { expectCallsAndReset } from '@s-libs/ng-dev';
import { reject } from './reject';

describe('reject()', () => {
it('works for objects', () => {
const object = { a: 1, b: 2, c: 3 };
expect(reject(object, (item) => item === 2)).toEqual([1, 3]);
expect(reject(object, (_item, key) => key === 'b')).toEqual([1, 3]);
});

//
// stolen from https://github.com/lodash/lodash
//

it('should return elements the `predicate` returns falsey for', () => {
expect(reject([1, 2, 3], (item) => item === 2)).toEqual([1, 3]);
});

it('should provide correct iteratee arguments', () => {
const spy = jasmine.createSpy();
reject([1, 2, 3], spy);
expect(spy.calls.first().args).toEqual([1, 0]);
});

it('should treat sparse arrays as dense', () => {
const array = [1];
array[2] = 3;
const spy = jasmine.createSpy();

reject(array, spy);

expectCallsAndReset(spy, [1, 0], [undefined, 1], [3, 2]);
});

it('should not iterate custom properties of arrays', () => {
const array = [1];
(array as any).a = 1;
const spy = jasmine.createSpy();

reject(array, spy);

expectCallsAndReset(spy, [1, 0]);
});

it('should ignore changes to `length`', () => {
const array = [1];
const spy = jasmine.createSpy().and.callFake(() => {
array.push(2);
return true;
});

reject(array, spy);

expect(spy).toHaveBeenCalledTimes(1);
});

it('should ignore added `object` properties', () => {
const object: any = { a: 1 };
const spy = jasmine.createSpy().and.callFake(() => {
object.b = 2;
return true;
});

reject(object, spy);

expect(spy).toHaveBeenCalledTimes(1);
});

it('should accept falsey arguments', () => {
expect(reject(null, () => true)).toEqual([]);
expect(reject(undefined, () => true)).toEqual([]);
});

it('should return an array', () => {
const array = [1, 2, 3];
const actual = reject(array, () => true);

expect(actual).toEqual(jasmine.any(Array));
expect(actual).not.toBe(array);
});
});
44 changes: 44 additions & 0 deletions projects/micro-dash/src/lib/collection/reject.ts
@@ -0,0 +1,44 @@
import {
ArrayIteratee,
ArrayNarrowingIteratee,
Cast,
KeyNarrowingIteratee,
Nil,
ObjectIteratee,
ValueNarrowingIteratee,
} from '../interfaces';
import { filter } from './filter';

/**
* The opposite of `filter`; this method returns the elements of `collection` that `predicate` does **not** return truthy for.
*
* Contribution to minified bundle size, when it is the only function imported:
* - Lodash: 14,253 bytes
* - Micro-dash: 349 bytes
*/

export function reject<I, O>(
array: readonly I[] | Nil,
predicate: ArrayNarrowingIteratee<O>,
): Array<Exclude<I, O>>;
export function reject<T>(
array: readonly T[] | Nil,
predicate: ArrayIteratee<T, boolean>,
): T[];

export function reject<I, O>(
object: I | Nil,
predicate: ValueNarrowingIteratee<I, O>,
): Array<Exclude<I[keyof I], O>>;
export function reject<I, O>(
object: I | Nil,
predicate: KeyNarrowingIteratee<I, O>,
): Array<{ [K in keyof I]: Cast<K, string> extends O ? never : I[K] }[keyof I]>;
export function reject<T>(
object: T | Nil,
predicate: ObjectIteratee<T, boolean>,
): Array<T[keyof T]>;

export function reject(collection: any, predicate: any): any[] {
return filter(collection, (value: any, key: any) => !predicate(value, key));
}

0 comments on commit 915db96

Please sign in to comment.